|
|
@@ -11,159 +11,66 @@ using LibHac.Ncm;
|
|
|
using LibHac.Ns;
|
|
|
using Ryujinx.Common.Configuration;
|
|
|
using Ryujinx.Common.Logging;
|
|
|
-using Ryujinx.Common.Utilities;
|
|
|
using Ryujinx.HLE.FileSystem;
|
|
|
using Ryujinx.HLE.HOS;
|
|
|
+using Ryujinx.Ui.Helper;
|
|
|
+using Ryujinx.Ui.Windows;
|
|
|
using System;
|
|
|
using System.Buffers;
|
|
|
using System.Collections.Generic;
|
|
|
-using System.Diagnostics;
|
|
|
using System.Globalization;
|
|
|
using System.IO;
|
|
|
-using System.Reflection;
|
|
|
using System.Threading;
|
|
|
|
|
|
using static LibHac.Fs.ApplicationSaveDataManagement;
|
|
|
|
|
|
-namespace Ryujinx.Ui
|
|
|
+namespace Ryujinx.Ui.Widgets
|
|
|
{
|
|
|
- public class GameTableContextMenu : Menu
|
|
|
+ public partial class GameTableContextMenu : Menu
|
|
|
{
|
|
|
- private readonly ListStore _gameTableStore;
|
|
|
- private readonly TreeIter _rowIter;
|
|
|
- private readonly VirtualFileSystem _virtualFileSystem;
|
|
|
-
|
|
|
+ private readonly MainWindow _parent;
|
|
|
+ private readonly VirtualFileSystem _virtualFileSystem;
|
|
|
private readonly BlitStruct<ApplicationControlProperty> _controlData;
|
|
|
|
|
|
+ private readonly string _titleFilePath;
|
|
|
+ private readonly string _titleName;
|
|
|
+ private readonly string _titleIdText;
|
|
|
+ private readonly ulong _titleId;
|
|
|
+
|
|
|
private MessageDialog _dialog;
|
|
|
private bool _cancel;
|
|
|
|
|
|
- public GameTableContextMenu(ListStore gameTableStore, BlitStruct<ApplicationControlProperty> controlData, TreeIter rowIter, VirtualFileSystem virtualFileSystem)
|
|
|
+ public GameTableContextMenu(MainWindow parent, VirtualFileSystem virtualFileSystem, string titleFilePath, string titleName, string titleId, BlitStruct<ApplicationControlProperty> controlData)
|
|
|
{
|
|
|
- _gameTableStore = gameTableStore;
|
|
|
- _rowIter = rowIter;
|
|
|
- _virtualFileSystem = virtualFileSystem;
|
|
|
- _controlData = controlData;
|
|
|
-
|
|
|
- MenuItem openSaveUserDir = new MenuItem("Open User Save Directory")
|
|
|
- {
|
|
|
- Sensitive = !Utilities.IsEmpty(controlData.ByteSpan) && controlData.Value.UserAccountSaveDataSize > 0,
|
|
|
- TooltipText = "Open the directory which contains Application's User Saves."
|
|
|
- };
|
|
|
-
|
|
|
- MenuItem openSaveDeviceDir = new MenuItem("Open Device Save Directory")
|
|
|
- {
|
|
|
- Sensitive = !Utilities.IsEmpty(controlData.ByteSpan) && controlData.Value.DeviceSaveDataSize > 0,
|
|
|
- TooltipText = "Open the directory which contains Application's Device Saves."
|
|
|
- };
|
|
|
-
|
|
|
- MenuItem openSaveBcatDir = new MenuItem("Open BCAT Save Directory")
|
|
|
- {
|
|
|
- Sensitive = !Utilities.IsEmpty(controlData.ByteSpan) && controlData.Value.BcatDeliveryCacheStorageSize > 0,
|
|
|
- TooltipText = "Open the directory which contains Application's BCAT Saves."
|
|
|
- };
|
|
|
-
|
|
|
- MenuItem manageTitleUpdates = new MenuItem("Manage Title Updates")
|
|
|
- {
|
|
|
- TooltipText = "Open the Title Update management window"
|
|
|
- };
|
|
|
+ _parent = parent;
|
|
|
|
|
|
- MenuItem manageDlc = new MenuItem("Manage DLC")
|
|
|
- {
|
|
|
- TooltipText = "Open the DLC management window"
|
|
|
- };
|
|
|
-
|
|
|
- MenuItem openTitleModDir = new MenuItem("Open Mods Directory")
|
|
|
- {
|
|
|
- TooltipText = "Open the directory which contains Application's Mods."
|
|
|
- };
|
|
|
-
|
|
|
- string ext = System.IO.Path.GetExtension(_gameTableStore.GetValue(_rowIter, 9).ToString()).ToLower();
|
|
|
- bool hasNca = ext == ".nca" || ext == ".nsp" || ext == ".pfs0" || ext == ".xci";
|
|
|
-
|
|
|
- MenuItem extractMenu = new MenuItem("Extract Data");
|
|
|
-
|
|
|
- MenuItem extractRomFs = new MenuItem("RomFS")
|
|
|
- {
|
|
|
- Sensitive = hasNca,
|
|
|
- TooltipText = "Extract the RomFS section from Application's current config (including updates)."
|
|
|
- };
|
|
|
+ InitializeComponent();
|
|
|
|
|
|
- MenuItem extractExeFs = new MenuItem("ExeFS")
|
|
|
- {
|
|
|
- Sensitive = hasNca,
|
|
|
- TooltipText = "Extract the ExeFS section from Application's current config (including updates)."
|
|
|
- };
|
|
|
+ _virtualFileSystem = virtualFileSystem;
|
|
|
+ _titleFilePath = titleFilePath;
|
|
|
+ _titleName = titleName;
|
|
|
+ _titleIdText = titleId;
|
|
|
+ _controlData = controlData;
|
|
|
|
|
|
- MenuItem extractLogo = new MenuItem("Logo")
|
|
|
+ if (!ulong.TryParse(_titleIdText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out _titleId))
|
|
|
{
|
|
|
- Sensitive = hasNca,
|
|
|
- TooltipText = "Extract the Logo section from Application's current config (including updates)."
|
|
|
- };
|
|
|
-
|
|
|
- Menu extractSubMenu = new Menu();
|
|
|
-
|
|
|
- extractSubMenu.Append(extractExeFs);
|
|
|
- extractSubMenu.Append(extractRomFs);
|
|
|
- extractSubMenu.Append(extractLogo);
|
|
|
+ GtkDialog.CreateErrorDialog("The selected game did not have a valid Title Id");
|
|
|
|
|
|
- extractMenu.Submenu = extractSubMenu;
|
|
|
-
|
|
|
- MenuItem managePtcMenu = new MenuItem("Cache Management");
|
|
|
-
|
|
|
- MenuItem purgePtcCache = new MenuItem("Purge PPTC Cache")
|
|
|
- {
|
|
|
- TooltipText = "Delete the Application's PPTC cache."
|
|
|
- };
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- MenuItem purgeShaderCache = new MenuItem("Purge Shader Cache")
|
|
|
- {
|
|
|
- TooltipText = "Delete the Application's shader cache."
|
|
|
- };
|
|
|
+ _openSaveUserDirMenuItem.Sensitive = !Utilities.IsEmpty(controlData.ByteSpan) && controlData.Value.UserAccountSaveDataSize > 0;
|
|
|
+ _openSaveDeviceDirMenuItem.Sensitive = !Utilities.IsEmpty(controlData.ByteSpan) && controlData.Value.DeviceSaveDataSize > 0;
|
|
|
+ _openSaveBcatDirMenuItem.Sensitive = !Utilities.IsEmpty(controlData.ByteSpan) && controlData.Value.BcatDeliveryCacheStorageSize > 0;
|
|
|
|
|
|
- MenuItem openPtcDir = new MenuItem("Open PPTC Directory")
|
|
|
- {
|
|
|
- TooltipText = "Open the directory which contains the Application's PPTC cache."
|
|
|
- };
|
|
|
+ string fileExt = System.IO.Path.GetExtension(_titleFilePath).ToLower();
|
|
|
+ bool hasNca = fileExt == ".nca" || fileExt == ".nsp" || fileExt == ".pfs0" || fileExt == ".xci";
|
|
|
|
|
|
- MenuItem openShaderCacheDir = new MenuItem("Open Shader Cache Directory")
|
|
|
- {
|
|
|
- TooltipText = "Open the directory which contains the Application's shader cache."
|
|
|
- };
|
|
|
+ _extractRomFsMenuItem.Sensitive = hasNca;
|
|
|
+ _extractExeFsMenuItem.Sensitive = hasNca;
|
|
|
+ _extractLogoMenuItem.Sensitive = hasNca;
|
|
|
|
|
|
- Menu manageSubMenu = new Menu();
|
|
|
-
|
|
|
- manageSubMenu.Append(purgePtcCache);
|
|
|
- manageSubMenu.Append(purgeShaderCache);
|
|
|
- manageSubMenu.Append(openPtcDir);
|
|
|
- manageSubMenu.Append(openShaderCacheDir);
|
|
|
-
|
|
|
- managePtcMenu.Submenu = manageSubMenu;
|
|
|
-
|
|
|
- openSaveUserDir.Activated += OpenSaveUserDir_Clicked;
|
|
|
- openSaveDeviceDir.Activated += OpenSaveDeviceDir_Clicked;
|
|
|
- openSaveBcatDir.Activated += OpenSaveBcatDir_Clicked;
|
|
|
- manageTitleUpdates.Activated += ManageTitleUpdates_Clicked;
|
|
|
- manageDlc.Activated += ManageDlc_Clicked;
|
|
|
- openTitleModDir.Activated += OpenTitleModDir_Clicked;
|
|
|
- extractRomFs.Activated += ExtractRomFs_Clicked;
|
|
|
- extractExeFs.Activated += ExtractExeFs_Clicked;
|
|
|
- extractLogo.Activated += ExtractLogo_Clicked;
|
|
|
- purgePtcCache.Activated += PurgePtcCache_Clicked;
|
|
|
- purgeShaderCache.Activated += PurgeShaderCache_Clicked;
|
|
|
- openPtcDir.Activated += OpenPtcDir_Clicked;
|
|
|
- openShaderCacheDir.Activated += OpenShaderCacheDir_Clicked;
|
|
|
-
|
|
|
- this.Add(openSaveUserDir);
|
|
|
- this.Add(openSaveDeviceDir);
|
|
|
- this.Add(openSaveBcatDir);
|
|
|
- this.Add(new SeparatorMenuItem());
|
|
|
- this.Add(manageTitleUpdates);
|
|
|
- this.Add(manageDlc);
|
|
|
- this.Add(openTitleModDir);
|
|
|
- this.Add(new SeparatorMenuItem());
|
|
|
- this.Add(managePtcMenu);
|
|
|
- this.Add(extractMenu);
|
|
|
+ PopupAtPointer(null);
|
|
|
}
|
|
|
|
|
|
private bool TryFindSaveData(string titleName, ulong titleId, BlitStruct<ApplicationControlProperty> controlHolder, SaveDataFilter filter, out ulong saveDataId)
|
|
|
@@ -178,7 +85,6 @@ namespace Ryujinx.Ui
|
|
|
using MessageDialog messageDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Question, ButtonsType.YesNo, null)
|
|
|
{
|
|
|
Title = "Ryujinx",
|
|
|
- Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
|
|
|
Text = $"There is no savedata for {titleName} [{titleId:x16}]",
|
|
|
SecondaryText = "Would you like to create savedata for this game?",
|
|
|
WindowPosition = WindowPosition.Center
|
|
|
@@ -191,7 +97,7 @@ namespace Ryujinx.Ui
|
|
|
|
|
|
ref ApplicationControlProperty control = ref controlHolder.Value;
|
|
|
|
|
|
- if (LibHac.Utilities.IsEmpty(controlHolder.ByteSpan))
|
|
|
+ if (Utilities.IsEmpty(controlHolder.ByteSpan))
|
|
|
{
|
|
|
// If the current application doesn't have a loaded control property, create a dummy one
|
|
|
// and set the savedata sizes so a user savedata will be created.
|
|
|
@@ -201,11 +107,10 @@ namespace Ryujinx.Ui
|
|
|
control.UserAccountSaveDataSize = 0x4000;
|
|
|
control.UserAccountSaveDataJournalSize = 0x4000;
|
|
|
|
|
|
- Logger.Warning?.Print(LogClass.Application,
|
|
|
- "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
|
|
|
+ Logger.Warning?.Print(LogClass.Application, "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
|
|
|
}
|
|
|
|
|
|
- Uid user = new Uid(1, 0);
|
|
|
+ Uid user = new Uid(1, 0); // TODO: Remove Hardcoded value.
|
|
|
|
|
|
result = EnsureApplicationSaveData(_virtualFileSystem.FsClient, out _, new LibHac.Ncm.ApplicationId(titleId), ref control, ref user);
|
|
|
|
|
|
@@ -232,8 +137,15 @@ namespace Ryujinx.Ui
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- private string GetSaveDataDirectory(ulong saveDataId)
|
|
|
+ private void OpenSaveDir(SaveDataFilter saveDataFilter)
|
|
|
{
|
|
|
+ saveDataFilter.SetProgramId(new ProgramId(_titleId));
|
|
|
+
|
|
|
+ if (!TryFindSaveData(_titleName, _titleId, _controlData, saveDataFilter, out ulong saveDataId))
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
string saveRootPath = System.IO.Path.Combine(_virtualFileSystem.GetNandPath(), $"user/save/{saveDataId:x16}");
|
|
|
|
|
|
if (!Directory.Exists(saveRootPath))
|
|
|
@@ -248,17 +160,19 @@ namespace Ryujinx.Ui
|
|
|
// If the committed directory exists, that path will be loaded the next time the savedata is mounted
|
|
|
if (Directory.Exists(committedPath))
|
|
|
{
|
|
|
- return committedPath;
|
|
|
+ OpenHelper.OpenFolder(committedPath);
|
|
|
}
|
|
|
-
|
|
|
- // If the working directory exists and the committed directory doesn't,
|
|
|
- // the working directory will be loaded the next time the savedata is mounted
|
|
|
- if (!Directory.Exists(workingPath))
|
|
|
+ else
|
|
|
{
|
|
|
- Directory.CreateDirectory(workingPath);
|
|
|
- }
|
|
|
+ // If the working directory exists and the committed directory doesn't,
|
|
|
+ // the working directory will be loaded the next time the savedata is mounted
|
|
|
+ if (!Directory.Exists(workingPath))
|
|
|
+ {
|
|
|
+ Directory.CreateDirectory(workingPath);
|
|
|
+ }
|
|
|
|
|
|
- return workingPath;
|
|
|
+ OpenHelper.OpenFolder(workingPath);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private void ExtractSection(NcaSectionType ncaSectionType, int programIndex = 0)
|
|
|
@@ -266,24 +180,21 @@ namespace Ryujinx.Ui
|
|
|
FileChooserDialog fileChooser = new FileChooserDialog("Choose the folder to extract into", null, FileChooserAction.SelectFolder, "Cancel", ResponseType.Cancel, "Extract", ResponseType.Accept);
|
|
|
fileChooser.SetPosition(WindowPosition.Center);
|
|
|
|
|
|
- int response = fileChooser.Run();
|
|
|
- string destination = fileChooser.Filename;
|
|
|
+ ResponseType response = (ResponseType)fileChooser.Run();
|
|
|
+ string destination = fileChooser.Filename;
|
|
|
|
|
|
fileChooser.Dispose();
|
|
|
|
|
|
- if (response == (int)ResponseType.Accept)
|
|
|
+ if (response == ResponseType.Accept)
|
|
|
{
|
|
|
Thread extractorThread = new Thread(() =>
|
|
|
{
|
|
|
- string sourceFile = _gameTableStore.GetValue(_rowIter, 9).ToString();
|
|
|
-
|
|
|
Gtk.Application.Invoke(delegate
|
|
|
{
|
|
|
_dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Cancel, null)
|
|
|
{
|
|
|
Title = "Ryujinx - NCA Section Extractor",
|
|
|
- Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
|
|
|
- SecondaryText = $"Extracting {ncaSectionType} section from {System.IO.Path.GetFileName(sourceFile)}...",
|
|
|
+ SecondaryText = $"Extracting {ncaSectionType} section from {System.IO.Path.GetFileName(_titleFilePath)}...",
|
|
|
WindowPosition = WindowPosition.Center
|
|
|
};
|
|
|
|
|
|
@@ -295,18 +206,18 @@ namespace Ryujinx.Ui
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- using (FileStream file = new FileStream(sourceFile, FileMode.Open, FileAccess.Read))
|
|
|
+ using (FileStream file = new FileStream(_titleFilePath, FileMode.Open, FileAccess.Read))
|
|
|
{
|
|
|
Nca mainNca = null;
|
|
|
Nca patchNca = null;
|
|
|
|
|
|
- if ((System.IO.Path.GetExtension(sourceFile).ToLower() == ".nsp") ||
|
|
|
- (System.IO.Path.GetExtension(sourceFile).ToLower() == ".pfs0") ||
|
|
|
- (System.IO.Path.GetExtension(sourceFile).ToLower() == ".xci"))
|
|
|
+ if ((System.IO.Path.GetExtension(_titleFilePath).ToLower() == ".nsp") ||
|
|
|
+ (System.IO.Path.GetExtension(_titleFilePath).ToLower() == ".pfs0") ||
|
|
|
+ (System.IO.Path.GetExtension(_titleFilePath).ToLower() == ".xci"))
|
|
|
{
|
|
|
PartitionFileSystem pfs;
|
|
|
|
|
|
- if (System.IO.Path.GetExtension(sourceFile) == ".xci")
|
|
|
+ if (System.IO.Path.GetExtension(_titleFilePath) == ".xci")
|
|
|
{
|
|
|
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());
|
|
|
|
|
|
@@ -338,7 +249,7 @@ namespace Ryujinx.Ui
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- else if (System.IO.Path.GetExtension(sourceFile).ToLower() == ".nca")
|
|
|
+ else if (System.IO.Path.GetExtension(_titleFilePath).ToLower() == ".nca")
|
|
|
{
|
|
|
mainNca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
|
|
|
}
|
|
|
@@ -355,7 +266,6 @@ namespace Ryujinx.Ui
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
(Nca updatePatchNca, _) = ApplicationLoader.GetGameUpdateData(_virtualFileSystem, mainNca.Header.TitleId.ToString("x16"), programIndex, out _);
|
|
|
|
|
|
if (updatePatchNca != null)
|
|
|
@@ -370,8 +280,8 @@ namespace Ryujinx.Ui
|
|
|
|
|
|
FileSystemClient fsClient = _virtualFileSystem.FsClient;
|
|
|
|
|
|
- string source = DateTime.Now.ToFileTime().ToString().Substring(10);
|
|
|
- string output = DateTime.Now.ToFileTime().ToString().Substring(10);
|
|
|
+ string source = DateTime.Now.ToFileTime().ToString()[10..];
|
|
|
+ string output = DateTime.Now.ToFileTime().ToString()[10..];
|
|
|
|
|
|
fsClient.Register(source.ToU8Span(), ncaFileSystem);
|
|
|
fsClient.Register(output.ToU8Span(), new LocalFileSystem(destination));
|
|
|
@@ -400,7 +310,6 @@ namespace Ryujinx.Ui
|
|
|
MessageDialog dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Ok, null)
|
|
|
{
|
|
|
Title = "Ryujinx - NCA Section Extractor",
|
|
|
- Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
|
|
|
SecondaryText = "Extraction has completed successfully.",
|
|
|
WindowPosition = WindowPosition.Center
|
|
|
};
|
|
|
@@ -510,111 +419,49 @@ namespace Ryujinx.Ui
|
|
|
return Result.Success;
|
|
|
}
|
|
|
|
|
|
+ //
|
|
|
// Events
|
|
|
+ //
|
|
|
private void OpenSaveUserDir_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string titleName = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[0];
|
|
|
- string titleId = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[1].ToLower();
|
|
|
-
|
|
|
- if (!ulong.TryParse(titleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdNumber))
|
|
|
- {
|
|
|
- GtkDialog.CreateErrorDialog("UI error: The selected game did not have a valid title ID");
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- SaveDataFilter filter = new SaveDataFilter();
|
|
|
- filter.SetUserId(new UserId(1, 0));
|
|
|
-
|
|
|
- OpenSaveDir(titleName, titleIdNumber, filter);
|
|
|
- }
|
|
|
-
|
|
|
- private void OpenSaveDir(string titleName, ulong titleId, SaveDataFilter filter)
|
|
|
- {
|
|
|
- filter.SetProgramId(new ProgramId(titleId));
|
|
|
-
|
|
|
- if (!TryFindSaveData(titleName, titleId, _controlData, filter, out ulong saveDataId))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- string saveDir = GetSaveDataDirectory(saveDataId);
|
|
|
+ SaveDataFilter saveDataFilter = new SaveDataFilter();
|
|
|
+ saveDataFilter.SetUserId(new UserId(1, 0)); // TODO: Remove Hardcoded value.
|
|
|
|
|
|
- Process.Start(new ProcessStartInfo
|
|
|
- {
|
|
|
- FileName = saveDir,
|
|
|
- UseShellExecute = true,
|
|
|
- Verb = "open"
|
|
|
- });
|
|
|
+ OpenSaveDir(saveDataFilter);
|
|
|
}
|
|
|
|
|
|
private void OpenSaveDeviceDir_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string titleName = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[0];
|
|
|
- string titleId = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[1].ToLower();
|
|
|
-
|
|
|
- if (!ulong.TryParse(titleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdNumber))
|
|
|
- {
|
|
|
- GtkDialog.CreateErrorDialog("UI error: The selected game did not have a valid title ID");
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- SaveDataFilter filter = new SaveDataFilter();
|
|
|
- filter.SetSaveDataType(SaveDataType.Device);
|
|
|
+ SaveDataFilter saveDataFilter = new SaveDataFilter();
|
|
|
+ saveDataFilter.SetSaveDataType(SaveDataType.Device);
|
|
|
|
|
|
- OpenSaveDir(titleName, titleIdNumber, filter);
|
|
|
+ OpenSaveDir(saveDataFilter);
|
|
|
}
|
|
|
|
|
|
private void OpenSaveBcatDir_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string titleName = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[0];
|
|
|
- string titleId = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[1].ToLower();
|
|
|
+ SaveDataFilter saveDataFilter = new SaveDataFilter();
|
|
|
+ saveDataFilter.SetSaveDataType(SaveDataType.Bcat);
|
|
|
|
|
|
- if (!ulong.TryParse(titleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdNumber))
|
|
|
- {
|
|
|
- GtkDialog.CreateErrorDialog("UI error: The selected game did not have a valid title ID");
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- SaveDataFilter filter = new SaveDataFilter();
|
|
|
- filter.SetSaveDataType(SaveDataType.Bcat);
|
|
|
-
|
|
|
- OpenSaveDir(titleName, titleIdNumber, filter);
|
|
|
+ OpenSaveDir(saveDataFilter);
|
|
|
}
|
|
|
|
|
|
private void ManageTitleUpdates_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string titleName = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[0];
|
|
|
- string titleId = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[1].ToLower();
|
|
|
-
|
|
|
- TitleUpdateWindow titleUpdateWindow = new TitleUpdateWindow(titleId, titleName, _virtualFileSystem);
|
|
|
- titleUpdateWindow.Show();
|
|
|
+ new TitleUpdateWindow(_parent, _virtualFileSystem, _titleIdText, _titleName).Show();
|
|
|
}
|
|
|
|
|
|
private void ManageDlc_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string titleName = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[0];
|
|
|
- string titleId = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[1].ToLower();
|
|
|
-
|
|
|
- DlcWindow dlcWindow = new DlcWindow(titleId, titleName, _virtualFileSystem);
|
|
|
- dlcWindow.Show();
|
|
|
+ new DlcWindow(_virtualFileSystem, _titleIdText, _titleName).Show();
|
|
|
}
|
|
|
|
|
|
private void OpenTitleModDir_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string titleId = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[1].ToLower();
|
|
|
-
|
|
|
- var modsBasePath = _virtualFileSystem.ModLoader.GetModsBasePath();
|
|
|
- var titleModsPath = _virtualFileSystem.ModLoader.GetTitleDir(modsBasePath, titleId);
|
|
|
+ string modsBasePath = _virtualFileSystem.ModLoader.GetModsBasePath();
|
|
|
+ string titleModsPath = _virtualFileSystem.ModLoader.GetTitleDir(modsBasePath, _titleIdText);
|
|
|
|
|
|
- Process.Start(new ProcessStartInfo
|
|
|
- {
|
|
|
- FileName = titleModsPath,
|
|
|
- UseShellExecute = true,
|
|
|
- Verb = "open"
|
|
|
- });
|
|
|
+ OpenHelper.OpenFolder(titleModsPath);
|
|
|
}
|
|
|
|
|
|
private void ExtractRomFs_Clicked(object sender, EventArgs args)
|
|
|
@@ -634,8 +481,7 @@ namespace Ryujinx.Ui
|
|
|
|
|
|
private void OpenPtcDir_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string titleId = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[1].ToLower();
|
|
|
- string ptcDir = System.IO.Path.Combine(AppDataManager.GamesDirPath, titleId, "cache", "cpu");
|
|
|
+ string ptcDir = System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "cpu");
|
|
|
|
|
|
string mainPath = System.IO.Path.Combine(ptcDir, "0");
|
|
|
string backupPath = System.IO.Path.Combine(ptcDir, "1");
|
|
|
@@ -646,52 +492,40 @@ namespace Ryujinx.Ui
|
|
|
Directory.CreateDirectory(mainPath);
|
|
|
Directory.CreateDirectory(backupPath);
|
|
|
}
|
|
|
-
|
|
|
- Process.Start(new ProcessStartInfo
|
|
|
- {
|
|
|
- FileName = ptcDir,
|
|
|
- UseShellExecute = true,
|
|
|
- Verb = "open"
|
|
|
- });
|
|
|
+
|
|
|
+ OpenHelper.OpenFolder(ptcDir);
|
|
|
}
|
|
|
|
|
|
private void OpenShaderCacheDir_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string titleId = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[1].ToLower();
|
|
|
- string shaderCacheDir = System.IO.Path.Combine(AppDataManager.GamesDirPath, titleId, "cache", "shader");
|
|
|
+ string shaderCacheDir = System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "shader");
|
|
|
|
|
|
if (!Directory.Exists(shaderCacheDir))
|
|
|
{
|
|
|
Directory.CreateDirectory(shaderCacheDir);
|
|
|
}
|
|
|
|
|
|
- Process.Start(new ProcessStartInfo
|
|
|
- {
|
|
|
- FileName = shaderCacheDir,
|
|
|
- UseShellExecute = true,
|
|
|
- Verb = "open"
|
|
|
- });
|
|
|
+ OpenHelper.OpenFolder(shaderCacheDir);
|
|
|
}
|
|
|
|
|
|
private void PurgePtcCache_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string[] tableEntry = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n");
|
|
|
- string titleId = tableEntry[1].ToLower();
|
|
|
-
|
|
|
- DirectoryInfo mainDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, titleId, "cache", "cpu", "0"));
|
|
|
- DirectoryInfo backupDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, titleId, "cache", "cpu", "1"));
|
|
|
-
|
|
|
- MessageDialog warningDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Warning, ButtonsType.YesNo, null)
|
|
|
- {
|
|
|
- Title = "Ryujinx - Warning",
|
|
|
- Text = $"You are about to delete the PPTC cache for '{tableEntry[0]}'. Are you sure you want to proceed?",
|
|
|
- WindowPosition = WindowPosition.Center
|
|
|
- };
|
|
|
+ DirectoryInfo mainDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "cpu", "0"));
|
|
|
+ DirectoryInfo backupDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "cpu", "1"));
|
|
|
+
|
|
|
+ MessageDialog warningDialog = GtkDialog.CreateConfirmationDialog("Warning", $"You are about to delete the PPTC cache for :\n\n<b>{_titleName}</b>\n\nAre you sure you want to proceed?");
|
|
|
|
|
|
List<FileInfo> cacheFiles = new List<FileInfo>();
|
|
|
|
|
|
- if (mainDir.Exists) { cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache")); }
|
|
|
- if (backupDir.Exists) { cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache")); }
|
|
|
+ if (mainDir.Exists)
|
|
|
+ {
|
|
|
+ cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache"));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (backupDir.Exists)
|
|
|
+ {
|
|
|
+ cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
|
|
|
+ }
|
|
|
|
|
|
if (cacheFiles.Count > 0 && warningDialog.Run() == (int)ResponseType.Yes)
|
|
|
{
|
|
|
@@ -703,7 +537,7 @@ namespace Ryujinx.Ui
|
|
|
}
|
|
|
catch(Exception e)
|
|
|
{
|
|
|
- Logger.Error?.Print(LogClass.Application, $"Error purging PPTC cache {file.Name}: {e}");
|
|
|
+ GtkDialog.CreateErrorDialog($"Error purging PPTC cache {file.Name}: {e}");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -713,21 +547,16 @@ namespace Ryujinx.Ui
|
|
|
|
|
|
private void PurgeShaderCache_Clicked(object sender, EventArgs args)
|
|
|
{
|
|
|
- string[] tableEntry = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n");
|
|
|
- string titleId = tableEntry[1].ToLower();
|
|
|
-
|
|
|
- DirectoryInfo shaderCacheDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, titleId, "cache", "shader"));
|
|
|
+ DirectoryInfo shaderCacheDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "shader"));
|
|
|
|
|
|
- MessageDialog warningDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Warning, ButtonsType.YesNo, null)
|
|
|
- {
|
|
|
- Title = "Ryujinx - Warning",
|
|
|
- Text = $"You are about to delete the shader cache for '{tableEntry[0]}'. Are you sure you want to proceed?",
|
|
|
- WindowPosition = WindowPosition.Center
|
|
|
- };
|
|
|
+ MessageDialog warningDialog = GtkDialog.CreateConfirmationDialog("Warning", $"You are about to delete the shader cache for :\n\n<b>{_titleName}</b>\n\nAre you sure you want to proceed?");
|
|
|
|
|
|
List<DirectoryInfo> cacheDirectory = new List<DirectoryInfo>();
|
|
|
|
|
|
- if (shaderCacheDir.Exists) { cacheDirectory.AddRange(shaderCacheDir.EnumerateDirectories("*")); }
|
|
|
+ if (shaderCacheDir.Exists)
|
|
|
+ {
|
|
|
+ cacheDirectory.AddRange(shaderCacheDir.EnumerateDirectories("*"));
|
|
|
+ }
|
|
|
|
|
|
if (cacheDirectory.Count > 0 && warningDialog.Run() == (int)ResponseType.Yes)
|
|
|
{
|
|
|
@@ -739,7 +568,7 @@ namespace Ryujinx.Ui
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
- Logger.Error?.Print(LogClass.Application, $"Error purging shader cache {directory.Name}: {e}");
|
|
|
+ GtkDialog.CreateErrorDialog($"Error purging shader cache {directory.Name}: {e}");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -747,4 +576,4 @@ namespace Ryujinx.Ui
|
|
|
warningDialog.Dispose();
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}
|