diff options
Diffstat (limited to 'src/yuzu/main.cpp')
-rw-r--r-- | src/yuzu/main.cpp | 185 |
1 files changed, 125 insertions, 60 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index cd7e78eb4..e704cc656 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -11,15 +11,19 @@ #endif // VFS includes must be before glad as they will conflict with Windows file api, which uses defines. +#include "applets/controller.h" #include "applets/error.h" #include "applets/profile_select.h" #include "applets/software_keyboard.h" #include "applets/web_browser.h" #include "configuration/configure_input.h" #include "configuration/configure_per_game.h" +#include "configuration/configure_vibration.h" #include "core/file_sys/vfs.h" #include "core/file_sys/vfs_real.h" +#include "core/frontend/applets/controller.h" #include "core/frontend/applets/general_frontend.h" +#include "core/frontend/applets/software_keyboard.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_oe.h" @@ -47,12 +51,14 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include <QDesktopServices> #include <QDesktopWidget> #include <QDialogButtonBox> +#include <QDir> #include <QFile> #include <QFileDialog> #include <QInputDialog> #include <QMessageBox> #include <QProgressBar> #include <QProgressDialog> +#include <QPushButton> #include <QShortcut> #include <QStatusBar> #include <QSysInfo> @@ -84,7 +90,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "core/file_sys/romfs.h" #include "core/file_sys/savedata_factory.h" #include "core/file_sys/submission_package.h" -#include "core/frontend/applets/software_keyboard.h" #include "core/hle/kernel/process.h" #include "core/hle/service/am/am.h" #include "core/hle/service/filesystem/filesystem.h" @@ -94,6 +99,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "core/perf_stats.h" #include "core/settings.h" #include "core/telemetry_session.h" +#include "input_common/main.h" #include "video_core/gpu.h" #include "video_core/shader_notify.h" #include "yuzu/about_dialog.h" @@ -186,9 +192,9 @@ static void InitializeLogging() { } GMainWindow::GMainWindow() - : config(new Config()), emu_thread(nullptr), - vfs(std::make_shared<FileSys::RealVfsFilesystem>()), - provider(std::make_unique<FileSys::ManualContentProvider>()) { + : input_subsystem{std::make_shared<InputCommon::InputSubsystem>()}, + config{std::make_unique<Config>()}, vfs{std::make_shared<FileSys::RealVfsFilesystem>()}, + provider{std::make_unique<FileSys::ManualContentProvider>()} { InitializeLogging(); LoadTranslation(); @@ -274,6 +280,8 @@ GMainWindow::GMainWindow() if (args.length() >= 2) { BootGame(args[1]); } + + MigrateConfigFiles(); } GMainWindow::~GMainWindow() { @@ -282,22 +290,37 @@ GMainWindow::~GMainWindow() { delete render_window; } +void GMainWindow::ControllerSelectorReconfigureControllers( + const Core::Frontend::ControllerParameters& parameters) { + QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get()); + + dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | + Qt::WindowTitleHint | Qt::WindowSystemMenuHint); + dialog.setWindowModality(Qt::WindowModal); + dialog.exec(); + + emit ControllerSelectorReconfigureFinished(); + + // Don't forget to apply settings. + Settings::Apply(); + config->Save(); + + UpdateStatusButtons(); +} + void GMainWindow::ProfileSelectorSelectProfile() { - const Service::Account::ProfileManager manager; - int index = 0; - if (manager.GetUserCount() != 1) { - QtProfileSelectionDialog dialog(this); - dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | - Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); - dialog.setWindowModality(Qt::WindowModal); - if (dialog.exec() == QDialog::Rejected) { - emit ProfileSelectorFinishedSelection(std::nullopt); - return; - } - index = dialog.GetIndex(); + QtProfileSelectionDialog dialog(this); + dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | + Qt::WindowTitleHint | Qt::WindowSystemMenuHint | + Qt::WindowCloseButtonHint); + dialog.setWindowModality(Qt::WindowModal); + if (dialog.exec() == QDialog::Rejected) { + emit ProfileSelectorFinishedSelection(std::nullopt); + return; } - const auto uuid = manager.GetUser(static_cast<std::size_t>(index)); + const Service::Account::ProfileManager manager; + const auto uuid = manager.GetUser(static_cast<std::size_t>(dialog.GetIndex())); if (!uuid.has_value()) { emit ProfileSelectorFinishedSelection(std::nullopt); return; @@ -309,8 +332,9 @@ void GMainWindow::ProfileSelectorSelectProfile() { void GMainWindow::SoftwareKeyboardGetText( const Core::Frontend::SoftwareKeyboardParameters& parameters) { QtSoftwareKeyboardDialog dialog(this, parameters); - dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | - Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); + dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | + Qt::WindowTitleHint | Qt::WindowSystemMenuHint | + Qt::WindowCloseButtonHint); dialog.setWindowModality(Qt::WindowModal); if (dialog.exec() == QDialog::Rejected) { @@ -473,7 +497,7 @@ void GMainWindow::InitializeWidgets() { #ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING ui.action_Report_Compatibility->setVisible(true); #endif - render_window = new GRenderWindow(this, emu_thread.get()); + render_window = new GRenderWindow(this, emu_thread.get(), input_subsystem); render_window->hide(); game_list = new GameList(vfs, provider.get(), this); @@ -529,13 +553,14 @@ void GMainWindow::InitializeWidgets() { dock_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton")); dock_status_button->setFocusPolicy(Qt::NoFocus); connect(dock_status_button, &QPushButton::clicked, [&] { - Settings::values.use_docked_mode = !Settings::values.use_docked_mode; - dock_status_button->setChecked(Settings::values.use_docked_mode); - OnDockedModeChanged(!Settings::values.use_docked_mode, Settings::values.use_docked_mode); + Settings::values.use_docked_mode.SetValue(!Settings::values.use_docked_mode.GetValue()); + dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue()); + OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(), + Settings::values.use_docked_mode.GetValue()); }); dock_status_button->setText(tr("DOCK")); dock_status_button->setCheckable(true); - dock_status_button->setChecked(Settings::values.use_docked_mode); + dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue()); statusBar()->insertPermanentWidget(0, dock_status_button); // Setup ASync button @@ -774,10 +799,11 @@ void GMainWindow::InitializeHotkeys() { }); connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Change Docked Mode"), this), &QShortcut::activated, this, [&] { - Settings::values.use_docked_mode = !Settings::values.use_docked_mode; - OnDockedModeChanged(!Settings::values.use_docked_mode, - Settings::values.use_docked_mode); - dock_status_button->setChecked(Settings::values.use_docked_mode); + Settings::values.use_docked_mode.SetValue( + !Settings::values.use_docked_mode.GetValue()); + OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(), + Settings::values.use_docked_mode.GetValue()); + dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue()); }); connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this), &QShortcut::activated, this, @@ -816,7 +842,7 @@ void GMainWindow::RestoreUIState() { OnDisplayTitleBars(ui.action_Display_Dock_Widget_Headers->isChecked()); ui.action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar); - game_list->setFilterVisible(ui.action_Show_Filter_Bar->isChecked()); + game_list->SetFilterVisible(ui.action_Show_Filter_Bar->isChecked()); ui.action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar); statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked()); @@ -965,13 +991,14 @@ bool GMainWindow::LoadROM(const QString& filename) { system.SetFilesystem(vfs); system.SetAppletFrontendSet({ - nullptr, // Parental Controls - std::make_unique<QtErrorDisplay>(*this), // - nullptr, // Photo Viewer - std::make_unique<QtProfileSelector>(*this), // - std::make_unique<QtSoftwareKeyboard>(*this), // - std::make_unique<QtWebBrowser>(*this), // - nullptr, // E-Commerce + std::make_unique<QtControllerSelector>(*this), // Controller Selector + nullptr, // E-Commerce + std::make_unique<QtErrorDisplay>(*this), // Error Display + nullptr, // Parental Controls + nullptr, // Photo Viewer + std::make_unique<QtProfileSelector>(*this), // Profile Selector + std::make_unique<QtSoftwareKeyboard>(*this), // Software Keyboard + std::make_unique<QtWebBrowser>(*this), // Web Browser }); system.RegisterHostThread(); @@ -1063,14 +1090,16 @@ void GMainWindow::BootGame(const QString& filename) { StoreRecentFile(filename); // Put the filename on top of the list u64 title_id{0}; - + auto& system = Core::System::GetInstance(); const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); - const auto loader = Loader::GetLoader(v_file); + const auto loader = Loader::GetLoader(system, v_file); if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) { // Load per game settings - Config per_game_config(fmt::format("{:016X}.ini", title_id), false); + Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig); } + ConfigureVibration::SetAllVibrationDevices(); + Settings::LogSettings(); if (UISettings::values.select_user_on_boot) { @@ -1115,9 +1144,13 @@ void GMainWindow::BootGame(const QString& filename) { std::string title_name; std::string title_version; - const auto res = Core::System::GetInstance().GetGameName(title_name); + const auto res = system.GetGameName(title_name); - const auto metadata = FileSys::PatchManager(title_id).GetControlMetadata(); + const auto metadata = [&system, title_id] { + const FileSys::PatchManager pm(title_id, system.GetFileSystemController(), + system.GetContentProvider()); + return pm.GetControlMetadata(); + }(); if (metadata.first != nullptr) { title_version = metadata.first->GetVersionString(); title_name = metadata.first->GetApplicationName(); @@ -1128,7 +1161,7 @@ void GMainWindow::BootGame(const QString& filename) { LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version); UpdateWindowTitle(title_name, title_version); - loading_screen->Prepare(Core::System::GetInstance().GetAppLoader()); + loading_screen->Prepare(system.GetAppLoader()); loading_screen->show(); emulation_running = true; @@ -1176,11 +1209,12 @@ void GMainWindow::ShutdownGame() { render_window->hide(); loading_screen->hide(); loading_screen->Clear(); - if (game_list->isEmpty()) + if (game_list->IsEmpty()) { game_list_placeholder->show(); - else + } else { game_list->show(); - game_list->setFilterFocus(); + } + game_list->SetFilterFocus(); setMouseTracking(false); ui.centralwidget->setMouseTracking(false); @@ -1246,16 +1280,18 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target const std::string& game_path) { std::string path; QString open_target; + auto& system = Core::System::GetInstance(); - const auto [user_save_size, device_save_size] = [this, &program_id, &game_path] { - FileSys::PatchManager pm{program_id}; + const auto [user_save_size, device_save_size] = [this, &game_path, &program_id, &system] { + const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), + system.GetContentProvider()}; const auto control = pm.GetControlMetadata().first; if (control != nullptr) { return std::make_pair(control->GetDefaultNormalSaveSize(), control->GetDeviceSaveDataSize()); } else { const auto file = Core::GetGameFileFromPath(vfs, game_path); - const auto loader = Loader::GetLoader(file); + const auto loader = Loader::GetLoader(system, file); FileSys::NACP nacp{}; loader->ReadControlData(nacp); @@ -1557,7 +1593,8 @@ void GMainWindow::RemoveCustomConfiguration(u64 program_id) { const QString config_dir = QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir)); const QString custom_config_file_path = - config_dir + QString::fromStdString(fmt::format("{:016X}.ini", program_id)); + config_dir + QStringLiteral("custom") + QDir::separator() + + QString::fromStdString(fmt::format("{:016X}.ini", program_id)); if (!QFile::exists(custom_config_file_path)) { QMessageBox::warning(this, tr("Error Removing Custom Configuration"), @@ -1581,7 +1618,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa "cancelled the operation.")); }; - const auto loader = Loader::GetLoader(vfs->OpenFile(game_path, FileSys::Mode::Read)); + auto& system = Core::System::GetInstance(); + const auto loader = Loader::GetLoader(system, vfs->OpenFile(game_path, FileSys::Mode::Read)); if (loader == nullptr) { failed(); return; @@ -1593,7 +1631,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa return; } - const auto& installed = Core::System::GetInstance().GetContentProvider(); + const auto& installed = system.GetContentProvider(); const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id); if (!romfs_title_id) { @@ -1608,7 +1646,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa if (*romfs_title_id == program_id) { const u64 ivfc_offset = loader->ReadRomFSIVFCOffset(); - FileSys::PatchManager pm{program_id}; + const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed}; romfs = pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program); } else { romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); @@ -1725,7 +1763,8 @@ void GMainWindow::OnGameListShowList(bool show) { void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) { u64 title_id{}; const auto v_file = Core::GetGameFileFromPath(vfs, file); - const auto loader = Loader::GetLoader(v_file); + const auto loader = Loader::GetLoader(Core::System::GetInstance(), v_file); + if (loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) { QMessageBox::information(this, tr("Properties"), tr("The game properties could not be loaded.")); @@ -2046,6 +2085,7 @@ 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"); @@ -2213,7 +2253,7 @@ void GMainWindow::OnConfigure() { const auto old_theme = UISettings::values.theme; const bool old_discord_presence = UISettings::values.enable_discord_presence; - ConfigureDialog configure_dialog(this, hotkey_registry); + ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get()); connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this, &GMainWindow::OnLanguageChanged); @@ -2337,11 +2377,11 @@ void GMainWindow::OnAbout() { } void GMainWindow::OnToggleFilterBar() { - game_list->setFilterVisible(ui.action_Show_Filter_Bar->isChecked()); + game_list->SetFilterVisible(ui.action_Show_Filter_Bar->isChecked()); if (ui.action_Show_Filter_Bar->isChecked()) { - game_list->setFilterFocus(); + game_list->SetFilterFocus(); } else { - game_list->clearFilter(); + game_list->ClearFilter(); } } @@ -2372,6 +2412,29 @@ void GMainWindow::OnCaptureScreenshot() { OnStartGame(); } +// TODO: Written 2020-10-01: Remove per-game config migration code when it is irrelevant +void GMainWindow::MigrateConfigFiles() { + const std::string& config_dir_str = Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir); + const QDir config_dir = QDir(QString::fromStdString(config_dir_str)); + const QStringList config_dir_list = config_dir.entryList(QStringList(QStringLiteral("*.ini"))); + + Common::FS::CreateFullPath(fmt::format("{}custom" DIR_SEP, config_dir_str)); + for (QStringList::const_iterator it = config_dir_list.constBegin(); + it != config_dir_list.constEnd(); ++it) { + const auto filename = it->toStdString(); + if (filename.find_first_not_of("0123456789abcdefACBDEF", 0) < 16) { + continue; + } + const auto origin = fmt::format("{}{}", config_dir_str, filename); + const auto destination = fmt::format("{}custom" DIR_SEP "{}", config_dir_str, filename); + LOG_INFO(Frontend, "Migrating config file from {} to {}", origin, destination); + if (!Common::FS::Rename(origin, destination)) { + // Delete the old config file if one already exists in the new location. + Common::FS::Delete(origin); + } + } +} + void GMainWindow::UpdateWindowTitle(const std::string& title_name, const std::string& title_version) { const auto full_name = std::string(Common::g_build_fullname); @@ -2429,7 +2492,7 @@ void GMainWindow::UpdateStatusBar() { } void GMainWindow::UpdateStatusButtons() { - dock_status_button->setChecked(Settings::values.use_docked_mode); + dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue()); multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); Settings::values.use_asynchronous_gpu_emulation.SetValue( Settings::values.use_asynchronous_gpu_emulation.GetValue() || @@ -2568,8 +2631,10 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) { const auto function = [this, &keys, &pdm] { keys.PopulateFromPartitionData(pdm); - Core::System::GetInstance().GetFileSystemController().CreateFactories(*vfs); - keys.DeriveETicket(pdm); + + auto& system = Core::System::GetInstance(); + system.GetFileSystemController().CreateFactories(*vfs); + keys.DeriveETicket(pdm, system.GetContentProvider()); }; QString errors; |