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.cpp130
1 files changed, 84 insertions, 46 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 41ba3c4c6..ca231d710 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -37,14 +37,20 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include <glad/glad.h>
#define QT_NO_OPENGL
+#include <QClipboard>
+#include <QDesktopServices>
#include <QDesktopWidget>
#include <QDialogButtonBox>
#include <QFile>
#include <QFileDialog>
+#include <QInputDialog>
#include <QMessageBox>
+#include <QProgressBar>
+#include <QProgressDialog>
+#include <QShortcut>
+#include <QStatusBar>
#include <QtConcurrent/QtConcurrent>
-#include <QtGui>
-#include <QtWidgets>
+
#include <fmt/format.h>
#include "common/common_paths.h"
#include "common/detached_tasks.h"
@@ -55,11 +61,9 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "common/microprofile.h"
#include "common/scm_rev.h"
#include "common/scope_exit.h"
-#include "common/string_util.h"
#include "common/telemetry.h"
#include "core/core.h"
#include "core/crypto/key_manager.h"
-#include "core/file_sys/bis_factory.h"
#include "core/file_sys/card_image.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h"
@@ -71,7 +75,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "core/frontend/applets/software_keyboard.h"
#include "core/hle/kernel/process.h"
#include "core/hle/service/filesystem/filesystem.h"
-#include "core/hle/service/filesystem/fsp_ldr.h"
#include "core/hle/service/nfp/nfp.h"
#include "core/hle/service/sm/sm.h"
#include "core/loader/loader.h"
@@ -87,7 +90,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "yuzu/configuration/configure_dialog.h"
#include "yuzu/debugger/console.h"
#include "yuzu/debugger/graphics/graphics_breakpoints.h"
-#include "yuzu/debugger/graphics/graphics_surface.h"
#include "yuzu/debugger/profiler.h"
#include "yuzu/debugger/wait_tree.h"
#include "yuzu/discord.h"
@@ -168,7 +170,8 @@ static void InitializeLogging() {
GMainWindow::GMainWindow()
: config(new Config()), emu_thread(nullptr),
- vfs(std::make_shared<FileSys::RealVfsFilesystem>()) {
+ vfs(std::make_shared<FileSys::RealVfsFilesystem>()),
+ provider(std::make_unique<FileSys::ManualContentProvider>()) {
InitializeLogging();
debug_context = Tegra::DebugContext::Construct();
@@ -200,11 +203,15 @@ GMainWindow::GMainWindow()
.arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));
show();
+ Core::System::GetInstance().SetContentProvider(
+ std::make_unique<FileSys::ContentProviderUnion>());
+ Core::System::GetInstance().RegisterContentProvider(
+ FileSys::ContentProviderUnionSlot::FrontendManual, provider.get());
+ Service::FileSystem::CreateFactories(*vfs);
+
// Gen keys if necessary
OnReinitializeKeys(ReinitializeKeyBehavior::NoWarning);
- // Necessary to load titles from nand in gamelist.
- Service::FileSystem::CreateFactories(*vfs);
game_list->LoadCompatibilityList();
game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
@@ -416,7 +423,7 @@ void GMainWindow::InitializeWidgets() {
render_window = new GRenderWindow(this, emu_thread.get());
render_window->hide();
- game_list = new GameList(vfs, this);
+ game_list = new GameList(vfs, provider.get(), this);
ui.horizontalLayout->addWidget(game_list);
loading_screen = new LoadingScreen(this);
@@ -475,11 +482,6 @@ void GMainWindow::InitializeDebugWidgets() {
graphicsBreakpointsWidget->hide();
debug_menu->addAction(graphicsBreakpointsWidget->toggleViewAction());
- graphicsSurfaceWidget = new GraphicsSurfaceWidget(debug_context, this);
- addDockWidget(Qt::RightDockWidgetArea, graphicsSurfaceWidget);
- graphicsSurfaceWidget->hide();
- debug_menu->addAction(graphicsSurfaceWidget->toggleViewAction());
-
waitTreeWidget = new WaitTreeWidget(this);
addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
waitTreeWidget->hide();
@@ -511,33 +513,34 @@ void GMainWindow::InitializeRecentFileMenuActions() {
}
void GMainWindow::InitializeHotkeys() {
- hotkey_registry.RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
- hotkey_registry.RegisterHotkey("Main Window", "Start Emulation");
- hotkey_registry.RegisterHotkey("Main Window", "Continue/Pause", QKeySequence(Qt::Key_F4));
- hotkey_registry.RegisterHotkey("Main Window", "Restart", QKeySequence(Qt::Key_F5));
- hotkey_registry.RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen);
- hotkey_registry.RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape),
- Qt::ApplicationShortcut);
- hotkey_registry.RegisterHotkey("Main Window", "Toggle Speed Limit", QKeySequence("CTRL+Z"),
- Qt::ApplicationShortcut);
- hotkey_registry.RegisterHotkey("Main Window", "Increase Speed Limit", QKeySequence("+"),
- Qt::ApplicationShortcut);
- hotkey_registry.RegisterHotkey("Main Window", "Decrease Speed Limit", QKeySequence("-"),
- Qt::ApplicationShortcut);
- hotkey_registry.RegisterHotkey("Main Window", "Load Amiibo", QKeySequence(Qt::Key_F2),
- Qt::ApplicationShortcut);
- hotkey_registry.RegisterHotkey("Main Window", "Capture Screenshot",
- QKeySequence(QKeySequence::Print));
- hotkey_registry.RegisterHotkey("Main Window", "Change Docked Mode", QKeySequence(Qt::Key_F10));
-
hotkey_registry.LoadHotkeys();
+ ui.action_Load_File->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Load File"));
+ ui.action_Load_File->setShortcutContext(
+ hotkey_registry.GetShortcutContext("Main Window", "Load File"));
+
+ ui.action_Exit->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Exit yuzu"));
+ ui.action_Exit->setShortcutContext(
+ hotkey_registry.GetShortcutContext("Main Window", "Exit yuzu"));
+
+ ui.action_Stop->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Stop Emulation"));
+ ui.action_Stop->setShortcutContext(
+ hotkey_registry.GetShortcutContext("Main Window", "Stop Emulation"));
+
+ ui.action_Show_Filter_Bar->setShortcut(
+ hotkey_registry.GetKeySequence("Main Window", "Toggle Filter Bar"));
+ ui.action_Show_Filter_Bar->setShortcutContext(
+ hotkey_registry.GetShortcutContext("Main Window", "Toggle Filter Bar"));
+
+ ui.action_Show_Status_Bar->setShortcut(
+ hotkey_registry.GetKeySequence("Main Window", "Toggle Status Bar"));
+ ui.action_Show_Status_Bar->setShortcutContext(
+ hotkey_registry.GetShortcutContext("Main Window", "Toggle Status Bar"));
+
connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated,
this, &GMainWindow::OnMenuLoadFile);
- connect(hotkey_registry.GetHotkey("Main Window", "Start Emulation", this),
- &QShortcut::activated, this, &GMainWindow::OnStartGame);
- connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause", this), &QShortcut::activated,
- this, [&] {
+ connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause Emulation", this),
+ &QShortcut::activated, this, [&] {
if (emulation_running) {
if (emu_thread->IsRunning()) {
OnPauseGame();
@@ -546,8 +549,8 @@ void GMainWindow::InitializeHotkeys() {
}
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Restart", this), &QShortcut::activated, this,
- [this] {
+ connect(hotkey_registry.GetHotkey("Main Window", "Restart Emulation", this),
+ &QShortcut::activated, this, [this] {
if (!Core::System::GetInstance().IsPoweredOn())
return;
BootGame(QString(game_path));
@@ -648,6 +651,8 @@ void GMainWindow::RestoreUIState() {
void GMainWindow::ConnectWidgetEvents() {
connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile);
connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder);
+ connect(game_list, &GameList::OpenTransferableShaderCacheRequested, this,
+ &GMainWindow::OnTransferableShaderCacheOpenFile);
connect(game_list, &GameList::DumpRomFSRequested, this, &GMainWindow::OnGameListDumpRomFS);
connect(game_list, &GameList::CopyTIDRequested, this, &GMainWindow::OnGameListCopyTID);
connect(game_list, &GameList::NavigateToGamedbEntryRequested, this,
@@ -692,7 +697,6 @@ void GMainWindow::ConnectMenuEvents() {
&GMainWindow::ToggleWindowMode);
connect(ui.action_Display_Dock_Widget_Headers, &QAction::triggered, this,
&GMainWindow::OnDisplayTitleBars);
- ui.action_Show_Filter_Bar->setShortcut(tr("CTRL+F"));
connect(ui.action_Show_Filter_Bar, &QAction::triggered, this, &GMainWindow::OnToggleFilterBar);
connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible);
@@ -1082,6 +1086,39 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
}
+void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
+ ASSERT(program_id != 0);
+
+ const QString tranferable_shader_cache_folder_path =
+ QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir)) + "opengl" +
+ DIR_SEP + "transferable";
+
+ const QString transferable_shader_cache_file_path =
+ tranferable_shader_cache_folder_path + DIR_SEP +
+ QString::fromStdString(fmt::format("{:016X}.bin", program_id));
+
+ if (!QFile::exists(transferable_shader_cache_file_path)) {
+ QMessageBox::warning(this, tr("Error Opening Transferable Shader Cache"),
+ tr("A shader cache for this title does not exist."));
+ return;
+ }
+
+ // Windows supports opening a folder with selecting a specified file in explorer. On every other
+ // OS we just open the transferable shader cache folder without preselecting the transferable
+ // shader cache file for the selected game.
+#if defined(Q_OS_WIN)
+ const QString explorer = QStringLiteral("explorer");
+ QStringList param;
+ if (!QFileInfo(transferable_shader_cache_file_path).isDir()) {
+ param << QStringLiteral("/select,");
+ }
+ param << QDir::toNativeSeparators(transferable_shader_cache_file_path);
+ QProcess::startDetached(explorer, param);
+#else
+ QDesktopServices::openUrl(QUrl::fromLocalFile(tranferable_shader_cache_folder_path));
+#endif
+}
+
static std::size_t CalculateRomFSEntrySize(const FileSys::VirtualDir& dir, bool full) {
std::size_t out = 0;
@@ -1141,7 +1178,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
return;
}
- const auto installed = Service::FileSystem::GetUnionContents();
+ const auto& installed = Core::System::GetInstance().GetContentProvider();
const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
if (!romfs_title_id) {
@@ -1624,6 +1661,7 @@ void GMainWindow::OnConfigure() {
auto result = configureDialog.exec();
if (result == QDialog::Accepted) {
configureDialog.applyConfiguration();
+ InitializeHotkeys();
if (UISettings::values.theme != old_theme)
UpdateUITheme();
if (UISettings::values.enable_discord_presence != old_discord_presence)
@@ -1886,14 +1924,14 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
}
}
-std::optional<u64> GMainWindow::SelectRomFSDumpTarget(
- const FileSys::RegisteredCacheUnion& installed, u64 program_id) {
+std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed,
+ u64 program_id) {
const auto dlc_entries =
installed.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
- std::vector<FileSys::RegisteredCacheEntry> dlc_match;
+ std::vector<FileSys::ContentProviderEntry> dlc_match;
dlc_match.reserve(dlc_entries.size());
std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
- [&program_id, &installed](const FileSys::RegisteredCacheEntry& entry) {
+ [&program_id, &installed](const FileSys::ContentProviderEntry& entry) {
return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == program_id &&
installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success;
});