From 9d411699d86538c21255642a2adecbace1ce33fc Mon Sep 17 00:00:00 2001
From: unknown <FreddyFunk@users.noreply.github.com>
Date: Fri, 8 Feb 2019 09:05:51 +0100
Subject: [PATCH 1/3] frontend: Open transferable shader cache for a selected
 game in the gamelist

---
 src/yuzu/game_list.cpp |  4 ++++
 src/yuzu/game_list.h   |  1 +
 src/yuzu/main.cpp      | 44 ++++++++++++++++++++++++++++++++++++++++++
 src/yuzu/main.h        |  1 +
 4 files changed, 50 insertions(+)

diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index c0e3c5fa9..4422a572b 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -329,6 +329,8 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
     QMenu context_menu;
     QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
     QAction* open_lfs_location = context_menu.addAction(tr("Open Mod Data Location"));
+    QAction* open_transferable_shader_cache =
+        context_menu.addAction(tr("Open Transferable Shader Cache"));
     context_menu.addSeparator();
     QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS"));
     QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard"));
@@ -344,6 +346,8 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
             [&]() { emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData); });
     connect(open_lfs_location, &QAction::triggered,
             [&]() { emit OpenFolderRequested(program_id, GameListOpenTarget::ModData); });
+    connect(open_transferable_shader_cache, &QAction::triggered,
+            [&]() { emit OpenTransferableShaderCacheRequested(program_id); });
     connect(dump_romfs, &QAction::triggered, [&]() { emit DumpRomFSRequested(program_id, path); });
     connect(copy_tid, &QAction::triggered, [&]() { emit CopyTIDRequested(program_id); });
     connect(navigate_to_gamedb_entry, &QAction::triggered,
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index b317eb2fc..8ea5cbaaa 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -66,6 +66,7 @@ signals:
     void GameChosen(QString game_path);
     void ShouldCancelWorker();
     void OpenFolderRequested(u64 program_id, GameListOpenTarget target);
+    void OpenTransferableShaderCacheRequested(u64 program_id);
     void DumpRomFSRequested(u64 program_id, const std::string& game_path);
     void CopyTIDRequested(u64 program_id);
     void NavigateToGamedbEntryRequested(u64 program_id,
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 1d460c189..b1df2760d 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -632,6 +632,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,
@@ -1066,6 +1068,48 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
     QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
 }
 
+void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
+    ASSERT(program_id != 0);
+
+    std::string transferable_shader_cache_file_path;
+    const std::string open_target = "Transferable Shader Cache";
+    const std::string tranferable_shader_cache_folder =
+        FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir) + "opengl" + DIR_SEP "transferable";
+
+    transferable_shader_cache_file_path.append(tranferable_shader_cache_folder);
+    transferable_shader_cache_file_path.append(DIR_SEP);
+    transferable_shader_cache_file_path.append(fmt::format("{:016X}", program_id));
+    transferable_shader_cache_file_path.append(".bin");
+
+    const QString qpath_transferable_shader_cache_file =
+        QString::fromStdString(transferable_shader_cache_file_path);
+
+    const QFile qfile(qpath_transferable_shader_cache_file);
+    if (!qfile.exists()) {
+        QMessageBox::warning(this,
+                             tr("Error Opening %1 File").arg(QString::fromStdString(open_target)),
+                             tr("File does not exist!"));
+        return;
+    }
+    LOG_INFO(Frontend, "Opening {} path for program_id={:016x}", open_target, program_id);
+
+    // 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 = "explorer";
+    QStringList param;
+    if (!QFileInfo(qpath_transferable_shader_cache_file).isDir())
+        param << QLatin1String("/select,");
+    param << QDir::toNativeSeparators(qpath_transferable_shader_cache_file);
+    QProcess::startDetached(explorer, param);
+#else
+    const QString qpath_transferable_shader_cache_folder =
+        QString::fromStdString(tranferable_shader_cache_folder);
+    QDesktopServices::openUrl(QUrl::fromLocalFile(qpath_transferable_shader_cache_folder));
+#endif
+}
+
 static std::size_t CalculateRomFSEntrySize(const FileSys::VirtualDir& dir, bool full) {
     std::size_t out = 0;
 
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index e07c892cf..7f3aa998e 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -176,6 +176,7 @@ private slots:
     /// Called whenever a user selects a game in the game list widget.
     void OnGameListLoadFile(QString game_path);
     void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target);
+    void OnTransferableShaderCacheOpenFile(u64 program_id);
     void OnGameListDumpRomFS(u64 program_id, const std::string& game_path);
     void OnGameListCopyTID(u64 program_id);
     void OnGameListNavigateToGamedbEntry(u64 program_id,

From 996ddb202b3dfdf7eed64532b3399a244ad0d5c2 Mon Sep 17 00:00:00 2001
From: Mat M <mathew1800@gmail.com>
Date: Fri, 8 Feb 2019 14:03:10 +0100
Subject: [PATCH 2/3] Use constexpr char array instead of string where
 applicable

Co-Authored-By: FreddyFunk <frederic.laing.development@gmail.com>
---
 src/yuzu/main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index b1df2760d..6d42bc67f 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1072,7 +1072,7 @@ void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
     ASSERT(program_id != 0);
 
     std::string transferable_shader_cache_file_path;
-    const std::string open_target = "Transferable Shader Cache";
+    constexpr char open_target[] = "Transferable Shader Cache";
     const std::string tranferable_shader_cache_folder =
         FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir) + "opengl" + DIR_SEP "transferable";
 

From f27c65eb91b6afe91995e957979f1164444c6edc Mon Sep 17 00:00:00 2001
From: unknown <FreddyFunk@users.noreply.github.com>
Date: Fri, 8 Feb 2019 14:18:41 +0100
Subject: [PATCH 3/3] Use QString instead of std::string where applicable

---
 src/yuzu/main.cpp | 28 +++++++++++-----------------
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 6d42bc67f..beba519b4 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1071,21 +1071,16 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
 void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
     ASSERT(program_id != 0);
 
-    std::string transferable_shader_cache_file_path;
     constexpr char open_target[] = "Transferable Shader Cache";
-    const std::string tranferable_shader_cache_folder =
-        FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir) + "opengl" + DIR_SEP "transferable";
+    const QString tranferable_shader_cache_folder_path =
+        QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir)) + "opengl" +
+        DIR_SEP + "transferable";
 
-    transferable_shader_cache_file_path.append(tranferable_shader_cache_folder);
-    transferable_shader_cache_file_path.append(DIR_SEP);
-    transferable_shader_cache_file_path.append(fmt::format("{:016X}", program_id));
-    transferable_shader_cache_file_path.append(".bin");
+    const QString transferable_shader_cache_file_path =
+        tranferable_shader_cache_folder_path + DIR_SEP +
+        QString::fromStdString(fmt::format("{:016X}", program_id)) + ".bin";
 
-    const QString qpath_transferable_shader_cache_file =
-        QString::fromStdString(transferable_shader_cache_file_path);
-
-    const QFile qfile(qpath_transferable_shader_cache_file);
-    if (!qfile.exists()) {
+    if (!QFile(transferable_shader_cache_file_path).exists()) {
         QMessageBox::warning(this,
                              tr("Error Opening %1 File").arg(QString::fromStdString(open_target)),
                              tr("File does not exist!"));
@@ -1099,14 +1094,13 @@ void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
 #if defined(Q_OS_WIN)
     const QString explorer = "explorer";
     QStringList param;
-    if (!QFileInfo(qpath_transferable_shader_cache_file).isDir())
+    if (!QFileInfo(transferable_shader_cache_file_path).isDir()) {
         param << QLatin1String("/select,");
-    param << QDir::toNativeSeparators(qpath_transferable_shader_cache_file);
+    }
+    param << QDir::toNativeSeparators(transferable_shader_cache_file_path);
     QProcess::startDetached(explorer, param);
 #else
-    const QString qpath_transferable_shader_cache_folder =
-        QString::fromStdString(tranferable_shader_cache_folder);
-    QDesktopServices::openUrl(QUrl::fromLocalFile(qpath_transferable_shader_cache_folder));
+    QDesktopServices::openUrl(QUrl::fromLocalFile(tranferable_shader_cache_folder_path));
 #endif
 }