From 8162477dc1a1fb4811884f04f43e4fe1602464bd Mon Sep 17 00:00:00 2001 From: SSimco <37044560+SSimco@users.noreply.github.com> Date: Thu, 24 Nov 2022 17:57:13 +0000 Subject: [PATCH] ui: Add Open Cemu folder & delete shader cache buttons (#524) * Add option to open UserDataPath folder * Add option to remove shader caches Co-authored-by: ssimco --- src/gui/MainWindow.cpp | 10 ++++++- src/gui/MainWindow.h | 1 + src/gui/components/wxGameList.cpp | 49 +++++++++++++++++++++++++++++++ src/gui/components/wxGameList.h | 2 ++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 6e7c15f9..7b275ef7 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -71,6 +71,7 @@ enum // file MAINFRAME_MENU_ID_FILE_LOAD = 20100, MAINFRAME_MENU_ID_FILE_INSTALL_UPDATE, + MAINFRAME_MENU_ID_FILE_OPEN_CEMU_FOLDER, MAINFRAME_MENU_ID_FILE_EXIT, MAINFRAME_MENU_ID_FILE_END_EMULATION, MAINFRAME_MENU_ID_FILE_RECENT_0, @@ -160,6 +161,7 @@ EVT_MOVE(MainWindow::OnMove) // file menu EVT_MENU(MAINFRAME_MENU_ID_FILE_LOAD, MainWindow::OnFileMenu) EVT_MENU(MAINFRAME_MENU_ID_FILE_INSTALL_UPDATE, MainWindow::OnInstallUpdate) +EVT_MENU(MAINFRAME_MENU_ID_FILE_OPEN_CEMU_FOLDER, MainWindow::OnOpenCemuFolder) EVT_MENU(MAINFRAME_MENU_ID_FILE_EXIT, MainWindow::OnFileExit) EVT_MENU(MAINFRAME_MENU_ID_FILE_END_EMULATION, MainWindow::OnFileMenu) EVT_MENU_RANGE(MAINFRAME_MENU_ID_FILE_RECENT_0 + 0, MAINFRAME_MENU_ID_FILE_RECENT_LAST, MainWindow::OnFileMenu) @@ -616,6 +618,11 @@ void MainWindow::OnFileMenu(wxCommandEvent& event) } } +void MainWindow::OnOpenCemuFolder(wxCommandEvent& event) +{ + wxLaunchDefaultApplication(ActiveSettings::GetUserDataPath().wstring()); +} + void MainWindow::OnInstallUpdate(wxCommandEvent& event) { while (true) @@ -1976,7 +1983,8 @@ void MainWindow::RecreateMenu() break; } m_fileMenuSeparator1 = m_fileMenu->AppendSeparator(); - + m_fileMenu->Append(MAINFRAME_MENU_ID_FILE_OPEN_CEMU_FOLDER, _("&Open Cemu folder")); + m_fileMenu->AppendSeparator(); } else { diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index faf83a99..38f44939 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -86,6 +86,7 @@ public: void OnMouseWheel(wxMouseEvent& event); void OnClose(wxCloseEvent& event); void OnFileMenu(wxCommandEvent& event); + void OnOpenCemuFolder(wxCommandEvent& event); void OnLaunchFromFile(wxLaunchGameEvent& event); void OnInstallUpdate(wxCommandEvent& event); void OnFileExit(wxCommandEvent& event); diff --git a/src/gui/components/wxGameList.cpp b/src/gui/components/wxGameList.cpp index be8d3c70..59483057 100644 --- a/src/gui/components/wxGameList.cpp +++ b/src/gui/components/wxGameList.cpp @@ -47,6 +47,25 @@ void _stripPathFilename(fs::path& path) path = path.parent_path(); } +std::list _getCachesPaths(const TitleId& titleId) +{ + std::list cachePaths{ + ActiveSettings::GetCachePath(L"shaderCache/driver/vk/{:016x}.bin", titleId), + ActiveSettings::GetCachePath(L"shaderCache/precompiled/{:016x}_spirv.bin", titleId), + ActiveSettings::GetCachePath(L"shaderCache/precompiled/{:016x}_gl.bin", titleId), + ActiveSettings::GetCachePath(L"shaderCache/transferable/{:016x}_shaders.bin", titleId), + ActiveSettings::GetCachePath(L"shaderCache/transferable/{:016x}_vkpipeline.bin", titleId)}; + + cachePaths.remove_if( + [](const fs::path& cachePath) + { + std::error_code ec; + return !fs::exists(cachePath, ec); + }); + + return cachePaths; +} + wxGameList::wxGameList(wxWindow* parent, wxWindowID id) : wxListCtrl(parent, id, wxDefaultPosition, wxDefaultSize, GetStyleFlags(Style::kList)), m_style(Style::kList) { @@ -504,6 +523,8 @@ enum ContextMenuEntries kContextMenuEditGraphicPacks, kContextMenuEditGameProfile, + kContextMenuRemoveCache, + kContextMenuStyleList, kContextMenuStyleIcon, kContextMenuStyleIconSmall, @@ -540,6 +561,9 @@ void wxGameList::OnContextMenu(wxContextMenuEvent& event) menu.Append(kContextMenuUpdateFolder, _("&Update directory"))->Enable(gameInfo.HasUpdate()); menu.Append(kContextMenuDLCFolder, _("&DLC directory"))->Enable(gameInfo.HasAOC()); + menu.AppendSeparator(); + menu.Append(kContextMenuRemoveCache, _("&Remove shader caches"))->Enable(!_getCachesPaths(gameInfo.GetBaseTitleId()).empty()); + menu.AppendSeparator(); menu.Append(kContextMenuEditGraphicPacks, _("&Edit graphic packs")); menu.Append(kContextMenuEditGameProfile, _("&Edit game profile")); @@ -647,6 +671,11 @@ void wxGameList::OnContextMenuSelected(wxCommandEvent& event) wxLaunchDefaultBrowser(wxHelper::FromUtf8(fmt::format("file:{}", _pathToUtf8(path)))); break; } + case kContextMenuRemoveCache: + { + RemoveCache(_getCachesPaths(gameInfo.GetBaseTitleId()), gameInfo.GetTitleName()); + break; + } case kContextMenuEditGraphicPacks: { wxTitleIdEvent open_event(wxEVT_OPEN_GRAPHIC_PACK, title_id); @@ -1055,6 +1084,26 @@ void wxGameList::HandleTitleListCallback(CafeTitleListCallbackEvent* evt) } } +void wxGameList::RemoveCache(const std::list& cachePaths, const std::string& titleName) +{ + wxMessageDialog dialog(this, fmt::format(fmt::runtime(_("Remove the shader caches for {}?").ToStdString()), titleName), _("Remove shader caches"), wxCENTRE | wxYES_NO | wxICON_EXCLAMATION); + dialog.SetYesNoLabels(_("Yes"), _("No")); + + const auto dialogResult = dialog.ShowModal(); + if (dialogResult != wxID_YES) + return; + std::list errs; + for (const fs::path& cachePath : cachePaths) + { + if (std::error_code ec; !fs::remove(cachePath, ec)) + errs.emplace_back(fmt::format("{} : {}", cachePath.string(), ec.message())); + } + if (errs.empty()) + wxMessageDialog(this, _("The shader caches were removed!"), _("Shader caches removed"), wxCENTRE | wxOK | wxICON_INFORMATION).ShowModal(); + else + wxMessageDialog(this, fmt::format(fmt::runtime(_("Failed to remove the shader caches:\n{}").ToStdString()), fmt::join(errs, "\n")), _("Error"), wxCENTRE | wxOK | wxICON_ERROR).ShowModal(); +} + void wxGameList::AsyncWorkerThread() { while (m_async_worker_active) diff --git a/src/gui/components/wxGameList.h b/src/gui/components/wxGameList.h index f8efd5d2..7776d7f6 100644 --- a/src/gui/components/wxGameList.h +++ b/src/gui/components/wxGameList.h @@ -111,6 +111,8 @@ private: void HandleTitleListCallback(struct CafeTitleListCallbackEvent* evt); + void RemoveCache(const std::list& cachePath, const std::string& titleName); + void AsyncWorkerThread(); void RequestLoadIconAsync(TitleId titleId); bool QueryIconForTitle(TitleId titleId, int& icon, int& iconSmall);