diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
index e60fac09b..2ccb67c70 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
@@ -15,7 +15,7 @@ namespace Ryujinx.UI.Common.Configuration
///
/// The current version of the file format
///
- public const int CurrentVersion = 52;
+ public const int CurrentVersion = 53;
///
/// Version of the configuration file format
@@ -266,6 +266,11 @@ namespace Ryujinx.UI.Common.Configuration
/// A list of directories containing games to be used to load games into the games list
///
public List GameDirs { get; set; }
+
+ ///
+ /// A list of directories containing DLC/updates the user wants to autoload during library refreshes
+ ///
+ public List AutoloadDirs { get; set; }
///
/// A list of file types to be hidden in the games List
diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
index 4cd85aa01..f9179d0c0 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
@@ -121,6 +121,11 @@ namespace Ryujinx.UI.Common.Configuration
/// A list of directories containing games to be used to load games into the games list
///
public ReactiveObject> GameDirs { get; private set; }
+
+ ///
+ /// A list of directories containing DLC/updates the user wants to autoload during library refreshes
+ ///
+ public ReactiveObject> AutoloadDirs { get; private set; }
///
/// A list of file types to be hidden in the games List
@@ -192,6 +197,7 @@ namespace Ryujinx.UI.Common.Configuration
GuiColumns = new Columns();
ColumnSort = new ColumnSortSettings();
GameDirs = new ReactiveObject>();
+ AutoloadDirs = new ReactiveObject>();
ShownFileTypes = new ShownFileTypeSettings();
WindowStartup = new WindowStartupSettings();
EnableCustomTheme = new ReactiveObject();
@@ -735,6 +741,7 @@ namespace Ryujinx.UI.Common.Configuration
SortAscending = UI.ColumnSort.SortAscending,
},
GameDirs = UI.GameDirs,
+ AutoloadDirs = UI.AutoloadDirs,
ShownFileTypes = new ShownFileTypes
{
NSP = UI.ShownFileTypes.NSP,
@@ -844,6 +851,7 @@ namespace Ryujinx.UI.Common.Configuration
UI.ColumnSort.SortColumnId.Value = 0;
UI.ColumnSort.SortAscending.Value = false;
UI.GameDirs.Value = new List();
+ UI.AutoloadDirs.Value = new List();
UI.ShownFileTypes.NSP.Value = true;
UI.ShownFileTypes.PFS0.Value = true;
UI.ShownFileTypes.XCI.Value = true;
@@ -1493,6 +1501,15 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileUpdated = true;
}
+
+ if (configurationFileFormat.Version < 53)
+ {
+ Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 53.");
+
+ configurationFileFormat.AutoloadDirs = new();
+
+ configurationFileUpdated = true;
+ }
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.ResScale.Value = configurationFileFormat.ResScale;
@@ -1556,6 +1573,7 @@ namespace Ryujinx.UI.Common.Configuration
UI.ColumnSort.SortColumnId.Value = configurationFileFormat.ColumnSort.SortColumnId;
UI.ColumnSort.SortAscending.Value = configurationFileFormat.ColumnSort.SortAscending;
UI.GameDirs.Value = configurationFileFormat.GameDirs;
+ UI.AutoloadDirs.Value = configurationFileFormat.AutoloadDirs;
UI.ShownFileTypes.NSP.Value = configurationFileFormat.ShownFileTypes.NSP;
UI.ShownFileTypes.PFS0.Value = configurationFileFormat.ShownFileTypes.PFS0;
UI.ShownFileTypes.XCI.Value = configurationFileFormat.ShownFileTypes.XCI;
diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index 6f050ec1b..339842616 100644
--- a/src/Ryujinx/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
@@ -106,6 +106,7 @@
"SettingsTabGeneralHideCursorOnIdle": "On Idle",
"SettingsTabGeneralHideCursorAlways": "Always",
"SettingsTabGeneralGameDirectories": "Game Directories",
+ "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories",
"SettingsTabGeneralAdd": "Add",
"SettingsTabGeneralRemove": "Remove",
"SettingsTabSystem": "System",
@@ -559,6 +560,9 @@
"AddGameDirBoxTooltip": "Enter a game directory to add to the list",
"AddGameDirTooltip": "Add a game directory to the list",
"RemoveGameDirTooltip": "Remove selected game directory",
+ "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list",
+ "AddAutoloadDirTooltip": "Add an autoload directory to the list",
+ "RemoveAutoloadDirTooltip": "Remove selected autoload directory",
"CustomThemeCheckTooltip": "Use a custom Avalonia theme for the GUI to change the appearance of the emulator menus",
"CustomThemePathTooltip": "Path to custom GUI theme",
"CustomThemeBrowseTooltip": "Browse for a custom GUI theme",
diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
index 9223e578d..57c576e1f 100644
--- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
@@ -44,7 +44,8 @@ namespace Ryujinx.Ava.UI.ViewModels
private int _graphicsBackendMultithreadingIndex;
private float _volume;
private bool _isVulkanAvailable = true;
- private bool _directoryChanged;
+ private bool _gameDirectoryChanged;
+ private bool _autoloadDirectoryChanged;
private readonly List _gpuIds = new();
private int _graphicsBackendIndex;
private int _scalingFilter;
@@ -115,12 +116,23 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool IsHypervisorAvailable => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
- public bool DirectoryChanged
+ public bool GameDirectoryChanged
{
- get => _directoryChanged;
+ get => _gameDirectoryChanged;
set
{
- _directoryChanged = value;
+ _gameDirectoryChanged = value;
+
+ OnPropertyChanged();
+ }
+ }
+
+ public bool AutoloadDirectoryChanged
+ {
+ get => _autoloadDirectoryChanged;
+ set
+ {
+ _autoloadDirectoryChanged = value;
OnPropertyChanged();
}
@@ -231,6 +243,7 @@ namespace Ryujinx.Ava.UI.ViewModels
internal AvaloniaList TimeZones { get; set; }
public AvaloniaList GameDirectories { get; set; }
+ public AvaloniaList AutoloadDirectories { get; set; }
public ObservableCollection AvailableGpus { get; set; }
public AvaloniaList NetworkInterfaceList
@@ -273,6 +286,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public SettingsViewModel()
{
GameDirectories = new AvaloniaList();
+ AutoloadDirectories = new AvaloniaList();
TimeZones = new AvaloniaList();
AvailableGpus = new ObservableCollection();
_validTzRegions = new List();
@@ -398,6 +412,9 @@ namespace Ryujinx.Ava.UI.ViewModels
GameDirectories.Clear();
GameDirectories.AddRange(config.UI.GameDirs.Value);
+
+ AutoloadDirectories.Clear();
+ AutoloadDirectories.AddRange(config.UI.AutoloadDirs.Value);
BaseStyleIndex = config.UI.BaseStyle.Value switch
{
@@ -489,11 +506,17 @@ namespace Ryujinx.Ava.UI.ViewModels
config.AutoloadContent.Value = AutoloadContent;
config.HideCursor.Value = (HideCursorMode)HideCursor;
- if (_directoryChanged)
+ if (_gameDirectoryChanged)
{
List gameDirs = new(GameDirectories);
config.UI.GameDirs.Value = gameDirs;
}
+
+ if (_autoloadDirectoryChanged)
+ {
+ List autoloadDirs = new(AutoloadDirectories);
+ config.UI.AutoloadDirs.Value = autoloadDirs;
+ }
config.UI.BaseStyle.Value = BaseStyleIndex switch
{
@@ -590,7 +613,8 @@ namespace Ryujinx.Ava.UI.ViewModels
SaveSettingsEvent?.Invoke();
- _directoryChanged = false;
+ _gameDirectoryChanged = false;
+ _autoloadDirectoryChanged = false;
}
private static void RevertIfNotSaved()
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
index 9d26effcc..4f25cbebf 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
@@ -88,7 +88,7 @@
Orientation="Vertical"
Spacing="10">
@@ -105,27 +105,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs
index 996d15cdb..70ca32306 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs
@@ -19,14 +19,14 @@ namespace Ryujinx.Ava.UI.Views.Settings
InitializeComponent();
}
- private async void AddButton_OnClick(object sender, RoutedEventArgs e)
+ private async void AddGameDirButton_OnClick(object sender, RoutedEventArgs e)
{
- string path = PathBox.Text;
+ string path = GameDirPathBox.Text;
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
{
ViewModel.GameDirectories.Add(path);
- ViewModel.DirectoryChanged = true;
+ ViewModel.GameDirectoryChanged = true;
}
else
{
@@ -40,25 +40,68 @@ namespace Ryujinx.Ava.UI.Views.Settings
if (result.Count > 0)
{
ViewModel.GameDirectories.Add(result[0].Path.LocalPath);
- ViewModel.DirectoryChanged = true;
+ ViewModel.GameDirectoryChanged = true;
}
}
}
}
- private void RemoveButton_OnClick(object sender, RoutedEventArgs e)
+ private void RemoveGameDirButton_OnClick(object sender, RoutedEventArgs e)
{
- int oldIndex = GameList.SelectedIndex;
+ int oldIndex = GameDirsList.SelectedIndex;
- foreach (string path in new List(GameList.SelectedItems.Cast()))
+ foreach (string path in new List(GameDirsList.SelectedItems.Cast()))
{
ViewModel.GameDirectories.Remove(path);
- ViewModel.DirectoryChanged = true;
+ ViewModel.GameDirectoryChanged = true;
}
- if (GameList.ItemCount > 0)
+ if (GameDirsList.ItemCount > 0)
{
- GameList.SelectedIndex = oldIndex < GameList.ItemCount ? oldIndex : 0;
+ GameDirsList.SelectedIndex = oldIndex < GameDirsList.ItemCount ? oldIndex : 0;
+ }
+ }
+
+ private async void AddAutoloadDirButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ string path = AutoloadDirPathBox.Text;
+
+ if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.AutoloadDirectories.Contains(path))
+ {
+ ViewModel.AutoloadDirectories.Add(path);
+ ViewModel.AutoloadDirectoryChanged = true;
+ }
+ else
+ {
+ if (this.GetVisualRoot() is Window window)
+ {
+ var result = await window.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
+ {
+ AllowMultiple = false,
+ });
+
+ if (result.Count > 0)
+ {
+ ViewModel.AutoloadDirectories.Add(result[0].Path.LocalPath);
+ ViewModel.AutoloadDirectoryChanged = true;
+ }
+ }
+ }
+ }
+
+ private void RemoveAutoloadDirButton_OnClick(object sender, RoutedEventArgs e)
+ {
+ int oldIndex = AutoloadDirsList.SelectedIndex;
+
+ foreach (string path in new List(AutoloadDirsList.SelectedItems.Cast()))
+ {
+ ViewModel.AutoloadDirectories.Remove(path);
+ ViewModel.AutoloadDirectoryChanged = true;
+ }
+
+ if (AutoloadDirsList.ItemCount > 0)
+ {
+ AutoloadDirsList.SelectedIndex = oldIndex < AutoloadDirsList.ItemCount ? oldIndex : 0;
}
}
}
diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
index 7947b4896..3b471fee8 100644
--- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
@@ -642,17 +642,18 @@ namespace Ryujinx.Ava.UI.Windows
TimeIt("updates", () => ApplicationLibrary.LoadTitleUpdates());
TimeIt("DLC", () => ApplicationLibrary.LoadDownloadableContents());
- if (ConfigurationState.Instance.AutoloadContent)
+ var autoloadDirs = ConfigurationState.Instance.UI.AutoloadDirs.Value;
+ if (autoloadDirs.Count > 0)
{
var updatesLoaded = 0;
TimeIt("auto updates",
() => updatesLoaded =
- ApplicationLibrary.AutoLoadTitleUpdates(ConfigurationState.Instance.UI.GameDirs));
+ ApplicationLibrary.AutoLoadTitleUpdates(autoloadDirs));
var dlcLoaded = 0;
TimeIt("auto dlc",
() => dlcLoaded =
- ApplicationLibrary.AutoLoadDownloadableContents(ConfigurationState.Instance.UI.GameDirs));
+ ApplicationLibrary.AutoLoadDownloadableContents(autoloadDirs));
ShowNewContentAddedDialog(dlcLoaded, updatesLoaded);
}
diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs
index 314501c52..4d7871886 100644
--- a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs
@@ -39,7 +39,7 @@ namespace Ryujinx.Ava.UI.Windows
{
InputPage.InputView?.SaveCurrentProfile();
- if (Owner is MainWindow window && ViewModel.DirectoryChanged)
+ if (Owner is MainWindow window && (ViewModel.GameDirectoryChanged || ViewModel.AutoloadDirectoryChanged))
{
window.LoadApplications();
}