Compare commits
15 Commits
Canary-1.2
...
Canary-1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fa714bb72 | ||
|
|
7c01633f13 | ||
|
|
27c5cba10b | ||
|
|
3525d5ecd4 | ||
|
|
6286501550 | ||
|
|
61ae427a4d | ||
|
|
19d2883a35 | ||
|
|
617c03119f | ||
|
|
e43d899e1d | ||
|
|
0cd09ea0c5 | ||
|
|
4135d74e4d | ||
|
|
bd29f658b1 | ||
|
|
df150f0788 | ||
|
|
e50198b37d | ||
|
|
f426945fec |
@@ -17,6 +17,7 @@
|
||||
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
||||
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
|
||||
<PackageVersion Include="Concentus" Version="2.2.0" />
|
||||
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
||||
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
||||
@@ -41,7 +42,7 @@
|
||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||
<PackageVersion Include="Gommon" Version="2.7.0" />
|
||||
<PackageVersion Include="Gommon" Version="2.7.0.1" />
|
||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||
<PackageVersion Include="SharpMetal" Version="1.0.0-preview21" />
|
||||
|
||||
@@ -6,18 +6,19 @@ using System.Linq;
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[Flags]
|
||||
public enum DirtyHacks : byte
|
||||
public enum DirtyHack : byte
|
||||
{
|
||||
Xc2MenuSoftlockFix = 1,
|
||||
ShaderCompilationThreadSleep = 2
|
||||
ShaderTranslationDelay = 2
|
||||
}
|
||||
|
||||
public record EnabledDirtyHack(DirtyHacks Hack, int Value)
|
||||
public readonly struct EnabledDirtyHack(DirtyHack hack, int value)
|
||||
{
|
||||
public static readonly byte[] PackedFormat = [8, 32];
|
||||
|
||||
private uint[] Raw => [(uint)Hack, (uint)Value.CoerceAtLeast(0)];
|
||||
|
||||
public DirtyHack Hack => hack;
|
||||
public int Value => value;
|
||||
|
||||
|
||||
|
||||
public ulong Pack() => Raw.PackBitFields(PackedFormat);
|
||||
|
||||
public static EnabledDirtyHack Unpack(ulong packedHack)
|
||||
@@ -26,16 +27,20 @@ namespace Ryujinx.Common.Configuration
|
||||
if (unpackedFields is not [var hack, var value])
|
||||
throw new ArgumentException(nameof(packedHack));
|
||||
|
||||
return new EnabledDirtyHack((DirtyHacks)hack, (int)value);
|
||||
return new EnabledDirtyHack((DirtyHack)hack, (int)value);
|
||||
}
|
||||
|
||||
private uint[] Raw => [(uint)Hack, (uint)Value.CoerceAtLeast(0)];
|
||||
|
||||
public static readonly byte[] PackedFormat = [8, 32];
|
||||
}
|
||||
|
||||
public class DirtyHackCollection : Dictionary<DirtyHacks, int>
|
||||
public class DirtyHacks : Dictionary<DirtyHack, int>
|
||||
{
|
||||
public DirtyHackCollection(IEnumerable<EnabledDirtyHack> hacks)
|
||||
public DirtyHacks(IEnumerable<EnabledDirtyHack> hacks)
|
||||
=> hacks.ForEach(edh => Add(edh.Hack, edh.Value));
|
||||
|
||||
public DirtyHackCollection(ulong[] packedHacks) : this(packedHacks.Select(EnabledDirtyHack.Unpack)) {}
|
||||
public DirtyHacks(ulong[] packedHacks) : this(packedHacks.Select(EnabledDirtyHack.Unpack)) {}
|
||||
|
||||
public ulong[] PackEntries()
|
||||
=> Entries.Select(it => it.Pack()).ToArray();
|
||||
@@ -45,11 +50,11 @@ namespace Ryujinx.Common.Configuration
|
||||
.Select(it => new EnabledDirtyHack(it.Key, it.Value))
|
||||
.ToArray();
|
||||
|
||||
public static implicit operator DirtyHackCollection(EnabledDirtyHack[] hacks) => new(hacks);
|
||||
public static implicit operator DirtyHackCollection(ulong[] packedHacks) => new(packedHacks);
|
||||
public static implicit operator DirtyHacks(EnabledDirtyHack[] hacks) => new(hacks);
|
||||
public static implicit operator DirtyHacks(ulong[] packedHacks) => new(packedHacks);
|
||||
|
||||
public new int this[DirtyHacks hack] => TryGetValue(hack, out var value) ? value : -1;
|
||||
public new int this[DirtyHack hack] => TryGetValue(hack, out var value) ? value : -1;
|
||||
|
||||
public bool IsEnabled(DirtyHacks hack) => ContainsKey(hack);
|
||||
public bool IsEnabled(DirtyHack hack) => ContainsKey(hack);
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,11 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// </summary>
|
||||
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
||||
|
||||
internal DirtyHackCollection DirtyHacks { get; }
|
||||
/// <summary>
|
||||
/// Enabled dirty hacks.
|
||||
/// Used for workarounds to emulator bugs we can't fix/don't know how to fix yet.
|
||||
/// </summary>
|
||||
internal DirtyHacks DirtyHacks { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -117,7 +121,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// Creates a new instance of the GPU emulation context.
|
||||
/// </summary>
|
||||
/// <param name="renderer">Host renderer</param>
|
||||
public GpuContext(IRenderer renderer, DirtyHackCollection hackCollection)
|
||||
public GpuContext(IRenderer renderer, DirtyHacks hacks)
|
||||
{
|
||||
Renderer = renderer;
|
||||
|
||||
@@ -140,7 +144,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
|
||||
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
||||
|
||||
DirtyHacks = hackCollection;
|
||||
DirtyHacks = hacks;
|
||||
|
||||
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
||||
}
|
||||
|
||||
@@ -367,8 +367,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_context.DirtyHacks.IsEnabled(DirtyHacks.ShaderCompilationThreadSleep))
|
||||
Thread.Sleep(_context.DirtyHacks[DirtyHacks.ShaderCompilationThreadSleep]);
|
||||
if (_context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay))
|
||||
Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]);
|
||||
|
||||
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
||||
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
||||
using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true);
|
||||
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
|
||||
|
||||
if (context.Device.DirtyHacks.IsEnabled(DirtyHacks.Xc2MenuSoftlockFix) && TitleIDs.CurrentApplication.Value == Xc2TitleId)
|
||||
if (context.Device.DirtyHacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix) && TitleIDs.CurrentApplication.Value == Xc2TitleId)
|
||||
{
|
||||
// Add a load-bearing sleep to avoid XC2 softlock
|
||||
// https://web.archive.org/web/20240728045136/https://github.com/Ryujinx/Ryujinx/issues/2357
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Ryujinx.HLE
|
||||
|
||||
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
|
||||
|
||||
public DirtyHackCollection DirtyHacks { get; }
|
||||
public DirtyHacks DirtyHacks { get; }
|
||||
|
||||
public Switch(HLEConfiguration configuration)
|
||||
{
|
||||
@@ -57,7 +57,7 @@ namespace Ryujinx.HLE
|
||||
: MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable;
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
DirtyHacks = new DirtyHackCollection(Configuration.Hacks);
|
||||
DirtyHacks = new DirtyHacks(Configuration.Hacks);
|
||||
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
|
||||
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
|
||||
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks);
|
||||
|
||||
@@ -314,7 +314,7 @@ namespace Ryujinx.Ava
|
||||
|
||||
_renderer.Window?.ChangeVSyncMode(e.NewValue);
|
||||
|
||||
_viewModel.ShowCustomVSyncIntervalPicker = (e.NewValue == VSyncMode.Custom);
|
||||
_viewModel.UpdateVSyncIntervalPicker();
|
||||
}
|
||||
|
||||
public void VSyncModeToggle()
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
<PackageReference Include="Avalonia.Svg" />
|
||||
<PackageReference Include="Avalonia.Svg.Skia" />
|
||||
<PackageReference Include="CommandLineParser" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
<PackageReference Include="DiscordRichPresence" />
|
||||
<PackageReference Include="DynamicData" />
|
||||
<PackageReference Include="FluentAvaloniaUI" />
|
||||
@@ -162,4 +163,4 @@
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="Assets\locales.json" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
x:DataType="viewModels:MainWindowViewModel">
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
<controls:ApplicationContextMenu x:Key="ApplicationContextMenu" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
@@ -26,10 +25,10 @@
|
||||
Padding="8"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ContextFlyout="{StaticResource ApplicationContextMenu}"
|
||||
SelectedItem="{Binding GridSelectedApplication}"
|
||||
ContextFlyout="{Binding GridAppContextMenu}"
|
||||
DoubleTapped="GameList_DoubleTapped"
|
||||
ItemsSource="{Binding AppsObservableList}"
|
||||
SelectionChanged="GameList_SelectionChanged">
|
||||
ItemsSource="{Binding AppsObservableList}">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel
|
||||
|
||||
@@ -26,11 +26,5 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
if (sender is ListBox { SelectedItem: ApplicationData selected })
|
||||
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
||||
}
|
||||
|
||||
public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
|
||||
{
|
||||
if (DataContext is MainWindowViewModel viewModel && sender is ListBox { SelectedItem: ApplicationData selected })
|
||||
viewModel.GridSelectedApplication = selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:converters="clr-namespace:Avalonia.Data.Converters;assembly=Avalonia.Base"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
Focusable="True"
|
||||
@@ -16,7 +15,6 @@
|
||||
x:DataType="viewModels:MainWindowViewModel">
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
<controls:ApplicationContextMenu x:Key="ApplicationContextMenu" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
@@ -28,10 +26,10 @@
|
||||
Padding="8"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ContextFlyout="{StaticResource ApplicationContextMenu}"
|
||||
SelectedItem="{Binding ListSelectedApplication}"
|
||||
ContextFlyout="{Binding ListAppContextMenu}"
|
||||
DoubleTapped="GameList_DoubleTapped"
|
||||
ItemsSource="{Binding AppsObservableList}"
|
||||
SelectionChanged="GameList_SelectionChanged">
|
||||
ItemsSource="{Binding AppsObservableList}">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel
|
||||
|
||||
@@ -30,12 +30,6 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
||||
}
|
||||
|
||||
public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
|
||||
{
|
||||
if (DataContext is MainWindowViewModel viewModel && sender is ListBox { SelectedItem: ApplicationData selected })
|
||||
viewModel.ListSelectedApplication = selected;
|
||||
}
|
||||
|
||||
private async void IdString_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not MainWindowViewModel mwvm)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Styling;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Ryujinx.Ava.Common;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Utilities.Configuration;
|
||||
@@ -8,42 +9,11 @@ using System;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
public class AboutWindowViewModel : BaseModel, IDisposable
|
||||
public partial class AboutWindowViewModel : BaseModel, IDisposable
|
||||
{
|
||||
private Bitmap _githubLogo;
|
||||
private Bitmap _discordLogo;
|
||||
|
||||
private string _version;
|
||||
|
||||
public Bitmap GithubLogo
|
||||
{
|
||||
get => _githubLogo;
|
||||
set
|
||||
{
|
||||
_githubLogo = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Bitmap DiscordLogo
|
||||
{
|
||||
get => _discordLogo;
|
||||
set
|
||||
{
|
||||
_discordLogo = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Version
|
||||
{
|
||||
get => _version;
|
||||
set
|
||||
{
|
||||
_version = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
[ObservableProperty] private Bitmap _githubLogo;
|
||||
[ObservableProperty] private Bitmap _discordLogo;
|
||||
[ObservableProperty] private string _version;
|
||||
|
||||
public string Developers => "GreemDev";
|
||||
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
public class BaseModel : INotifyPropertyChanged
|
||||
public class BaseModel : ObservableObject
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
protected void OnPropertiesChanged(string firstPropertyName, params ReadOnlySpan<string> propertyNames)
|
||||
{
|
||||
OnPropertyChanged(firstPropertyName);
|
||||
|
||||
@@ -2,6 +2,7 @@ using Avalonia.Collections;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using DynamicData;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
@@ -17,13 +18,13 @@ using Application = Avalonia.Application;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
public class DownloadableContentManagerViewModel : BaseModel
|
||||
public partial class DownloadableContentManagerViewModel : BaseModel
|
||||
{
|
||||
private readonly ApplicationLibrary _applicationLibrary;
|
||||
private AvaloniaList<DownloadableContentModel> _downloadableContents = new();
|
||||
private AvaloniaList<DownloadableContentModel> _selectedDownloadableContents = new();
|
||||
private AvaloniaList<DownloadableContentModel> _views = new();
|
||||
private bool _showBundledContentNotice = false;
|
||||
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _selectedDownloadableContents = new();
|
||||
[ObservableProperty] private AvaloniaList<DownloadableContentModel> _views = new();
|
||||
[ObservableProperty] private bool _showBundledContentNotice = false;
|
||||
|
||||
private string _search;
|
||||
private readonly ApplicationData _applicationData;
|
||||
@@ -41,26 +42,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public AvaloniaList<DownloadableContentModel> Views
|
||||
{
|
||||
get => _views;
|
||||
set
|
||||
{
|
||||
_views = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public AvaloniaList<DownloadableContentModel> SelectedDownloadableContents
|
||||
{
|
||||
get => _selectedDownloadableContents;
|
||||
set
|
||||
{
|
||||
_selectedDownloadableContents = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
@@ -77,26 +58,13 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
get => string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowHeading], DownloadableContents.Count);
|
||||
}
|
||||
|
||||
public bool ShowBundledContentNotice
|
||||
{
|
||||
get => _showBundledContentNotice;
|
||||
set
|
||||
{
|
||||
_showBundledContentNotice = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public DownloadableContentManagerViewModel(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
||||
{
|
||||
_applicationLibrary = applicationLibrary;
|
||||
|
||||
_applicationData = applicationData;
|
||||
|
||||
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
_storageProvider = desktop.MainWindow.StorageProvider;
|
||||
}
|
||||
_storageProvider = RyujinxApp.MainWindow.StorageProvider;
|
||||
|
||||
LoadDownloadableContents();
|
||||
}
|
||||
|
||||
@@ -245,9 +245,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
{
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
_mainWindow =
|
||||
(MainWindow)((IClassicDesktopStyleApplicationLifetime)Application.Current
|
||||
.ApplicationLifetime).MainWindow;
|
||||
_mainWindow = RyujinxApp.MainWindow;
|
||||
|
||||
AvaloniaKeyboardDriver = new AvaloniaKeyboardDriver(owner);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using Avalonia.Media;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using DynamicData;
|
||||
using DynamicData.Binding;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
@@ -54,77 +55,112 @@ using ShaderCacheLoadingState = Ryujinx.Graphics.Gpu.Shader.ShaderCacheState;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : BaseModel
|
||||
public partial class MainWindowViewModel : BaseModel
|
||||
{
|
||||
private const int HotKeyPressDelayMs = 500;
|
||||
private delegate int LoadContentFromFolderDelegate(List<string> dirs, out int numRemoved);
|
||||
|
||||
private ObservableCollectionExtended<ApplicationData> _applications;
|
||||
private string _aspectStatusText;
|
||||
|
||||
private string _loadHeading;
|
||||
private string _cacheLoadStatus;
|
||||
private string _searchText;
|
||||
private Timer _searchTimer;
|
||||
private string _dockedStatusText;
|
||||
private string _vSyncModeText;
|
||||
private string _fifoStatusText;
|
||||
private string _gameStatusText;
|
||||
private string _volumeStatusText;
|
||||
private string _gpuStatusText;
|
||||
private string _shaderCountText;
|
||||
[ObservableProperty] private ObservableCollectionExtended<ApplicationData> _applications;
|
||||
[ObservableProperty] private string _aspectRatioStatusText;
|
||||
[ObservableProperty] private string _loadHeading;
|
||||
[ObservableProperty] private string _cacheLoadStatus;
|
||||
[ObservableProperty] private string _dockedStatusText;
|
||||
[ObservableProperty] private string _fifoStatusText;
|
||||
[ObservableProperty] private string _gameStatusText;
|
||||
[ObservableProperty] private string _volumeStatusText;
|
||||
[ObservableProperty] private string _gpuNameText;
|
||||
[ObservableProperty] private string _backendText;
|
||||
[ObservableProperty] private string _shaderCountText;
|
||||
[ObservableProperty] private bool _showShaderCompilationHint;
|
||||
[ObservableProperty] private bool _isFullScreen;
|
||||
[ObservableProperty] private int _progressMaximum;
|
||||
[ObservableProperty] private int _progressValue;
|
||||
[ObservableProperty] private bool _showMenuAndStatusBar = true;
|
||||
[ObservableProperty] private bool _showStatusSeparator;
|
||||
[ObservableProperty] private Brush _progressBarForegroundColor;
|
||||
[ObservableProperty] private Brush _progressBarBackgroundColor;
|
||||
[ObservableProperty] private Brush _vSyncModeColor;
|
||||
[ObservableProperty] private byte[] _selectedIcon;
|
||||
[ObservableProperty] private int _statusBarProgressMaximum;
|
||||
[ObservableProperty] private int _statusBarProgressValue;
|
||||
[ObservableProperty] private string _statusBarProgressStatusText;
|
||||
[ObservableProperty] private bool _statusBarProgressStatusVisible;
|
||||
[ObservableProperty] private bool _isPaused;
|
||||
[ObservableProperty] private bool _isLoadingIndeterminate = true;
|
||||
[ObservableProperty] private bool _showAll;
|
||||
[ObservableProperty] private string _lastScannedAmiiboId;
|
||||
[ObservableProperty] private ReadOnlyObservableCollection<ApplicationData> _appsObservableList;
|
||||
[ObservableProperty] private long _lastFullscreenToggle = Environment.TickCount64;
|
||||
[ObservableProperty] private bool _showContent = true;
|
||||
[ObservableProperty] private float _volumeBeforeMute;
|
||||
[ObservableProperty] private bool _areMimeTypesRegistered = FileAssociationHelper.AreMimeTypesRegistered;
|
||||
[ObservableProperty] private Cursor _cursor;
|
||||
[ObservableProperty] private string _title;
|
||||
[ObservableProperty] private WindowState _windowState;
|
||||
[ObservableProperty] private double _windowWidth;
|
||||
[ObservableProperty] private double _windowHeight;
|
||||
[ObservableProperty] private bool _isActive;
|
||||
[ObservableProperty] private bool _isSubMenuOpen;
|
||||
[ObservableProperty] private ApplicationContextMenu _listAppContextMenu;
|
||||
[ObservableProperty] private ApplicationContextMenu _gridAppContextMenu;
|
||||
|
||||
private bool _showLoadProgress;
|
||||
private bool _isGameRunning;
|
||||
private bool _isAmiiboRequested;
|
||||
private bool _isAmiiboBinRequested;
|
||||
private bool _showShaderCompilationHint;
|
||||
private bool _isGameRunning;
|
||||
private bool _isFullScreen;
|
||||
private int _progressMaximum;
|
||||
private int _progressValue;
|
||||
private long _lastFullscreenToggle = Environment.TickCount64;
|
||||
private bool _showLoadProgress;
|
||||
private bool _showMenuAndStatusBar = true;
|
||||
private bool _showStatusSeparator;
|
||||
private Brush _progressBarForegroundColor;
|
||||
private Brush _progressBarBackgroundColor;
|
||||
private Brush _vSyncModeColor;
|
||||
private byte[] _selectedIcon;
|
||||
private bool _isAppletMenuActive;
|
||||
private int _statusBarProgressMaximum;
|
||||
private int _statusBarProgressValue;
|
||||
private string _statusBarProgressStatusText;
|
||||
private bool _statusBarProgressStatusVisible;
|
||||
private bool _isPaused;
|
||||
private bool _showContent = true;
|
||||
private bool _isLoadingIndeterminate = true;
|
||||
private bool _showAll;
|
||||
private string _lastScannedAmiiboId;
|
||||
private bool _statusBarVisible;
|
||||
private ReadOnlyObservableCollection<ApplicationData> _appsObservableList;
|
||||
|
||||
private string _searchText;
|
||||
private Timer _searchTimer;
|
||||
private string _vSyncModeText;
|
||||
private string _showUiKey = "F4";
|
||||
private string _pauseKey = "F5";
|
||||
private string _screenshotKey = "F8";
|
||||
private float _volume;
|
||||
private float _volumeBeforeMute;
|
||||
private string _backendText;
|
||||
|
||||
private bool _areMimeTypesRegistered = FileAssociationHelper.AreMimeTypesRegistered;
|
||||
private bool _isAppletMenuActive;
|
||||
private bool _statusBarVisible;
|
||||
private bool _canUpdate = true;
|
||||
private Cursor _cursor;
|
||||
private string _title;
|
||||
private ApplicationData _currentApplicationData;
|
||||
private readonly AutoResetEvent _rendererWaitEvent;
|
||||
private WindowState _windowState;
|
||||
private double _windowWidth;
|
||||
private double _windowHeight;
|
||||
private int _customVSyncInterval;
|
||||
private int _customVSyncIntervalPercentageProxy;
|
||||
private ApplicationData _listSelectedApplication;
|
||||
private ApplicationData _gridSelectedApplication;
|
||||
|
||||
public ApplicationData ListSelectedApplication
|
||||
{
|
||||
get => _listSelectedApplication;
|
||||
set
|
||||
{
|
||||
_listSelectedApplication = value;
|
||||
|
||||
private bool _isActive;
|
||||
private bool _isSubMenuOpen;
|
||||
#pragma warning disable MVVMTK0034
|
||||
if (_listSelectedApplication != null && _listAppContextMenu == null)
|
||||
|
||||
public ApplicationData ListSelectedApplication;
|
||||
public ApplicationData GridSelectedApplication;
|
||||
ListAppContextMenu = new ApplicationContextMenu();
|
||||
else if (_listSelectedApplication == null && _listAppContextMenu != null)
|
||||
ListAppContextMenu = null!;
|
||||
#pragma warning restore MVVMTK0034
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationData GridSelectedApplication
|
||||
{
|
||||
get => _gridSelectedApplication;
|
||||
set
|
||||
{
|
||||
_gridSelectedApplication = value;
|
||||
|
||||
#pragma warning disable MVVMTK0034
|
||||
if (_gridSelectedApplication != null && _gridAppContextMenu == null)
|
||||
GridAppContextMenu = new ApplicationContextMenu();
|
||||
else if (_gridSelectedApplication == null && _gridAppContextMenu != null)
|
||||
GridAppContextMenu = null!;
|
||||
#pragma warning restore MVVMTK0034
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// Key is Title ID
|
||||
public SafeDictionary<string, LdnGameData.Array> LdnData = [];
|
||||
@@ -218,7 +254,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public bool CanUpdate
|
||||
{
|
||||
get => _canUpdate && EnableNonGameRunningControls && Updater.CanUpdate(false);
|
||||
get => _canUpdate && EnableNonGameRunningControls && Updater.CanUpdate();
|
||||
set
|
||||
{
|
||||
_canUpdate = value;
|
||||
@@ -226,49 +262,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public Cursor Cursor
|
||||
{
|
||||
get => _cursor;
|
||||
set
|
||||
{
|
||||
_cursor = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlyObservableCollection<ApplicationData> AppsObservableList
|
||||
{
|
||||
get => _appsObservableList;
|
||||
set
|
||||
{
|
||||
_appsObservableList = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPaused
|
||||
{
|
||||
get => _isPaused;
|
||||
set
|
||||
{
|
||||
_isPaused = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public long LastFullscreenToggle
|
||||
{
|
||||
get => _lastFullscreenToggle;
|
||||
set
|
||||
{
|
||||
_lastFullscreenToggle = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool StatusBarVisible
|
||||
{
|
||||
get => _statusBarVisible && EnableNonGameRunningControls;
|
||||
@@ -284,17 +277,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public bool ShowFirmwareStatus => !ShowLoadProgress;
|
||||
|
||||
public bool ShowShaderCompilationHint
|
||||
{
|
||||
get => _showShaderCompilationHint;
|
||||
set
|
||||
{
|
||||
_showShaderCompilationHint = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsGameRunning
|
||||
{
|
||||
get => _isGameRunning;
|
||||
@@ -337,7 +319,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
|
||||
public bool CanScanAmiiboBinaries => AmiiboBinReader.HasAmiiboKeyFile;
|
||||
|
||||
|
||||
public bool ShowLoadProgress
|
||||
{
|
||||
get => _showLoadProgress;
|
||||
@@ -350,61 +332,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public string GameStatusText
|
||||
{
|
||||
get => _gameStatusText;
|
||||
set
|
||||
{
|
||||
_gameStatusText = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsFullScreen
|
||||
{
|
||||
get => _isFullScreen;
|
||||
set
|
||||
{
|
||||
_isFullScreen = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSubMenuOpen
|
||||
{
|
||||
get => _isSubMenuOpen;
|
||||
set
|
||||
{
|
||||
_isSubMenuOpen = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowAll
|
||||
{
|
||||
get => _showAll;
|
||||
set
|
||||
{
|
||||
_showAll = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string LastScannedAmiiboId
|
||||
{
|
||||
get => _lastScannedAmiiboId;
|
||||
set
|
||||
{
|
||||
_lastScannedAmiiboId = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationData SelectedApplication
|
||||
{
|
||||
get
|
||||
@@ -418,87 +345,20 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool OpenUserSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0;
|
||||
public bool OpenUserSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0;
|
||||
|
||||
public bool OpenDeviceSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0;
|
||||
public bool OpenDeviceSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0;
|
||||
|
||||
public bool TrimXCIEnabled => XCIFileTrimmer.CanTrim(SelectedApplication.Path, new XCITrimmerLog.MainWindow(this));
|
||||
|
||||
public bool OpenBcatSaveDirectoryEnabled => !SelectedApplication.ControlHolder.ByteSpan.IsZeros() && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
|
||||
public bool OpenBcatSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
|
||||
|
||||
public string LoadHeading
|
||||
public bool ShowCustomVSyncIntervalPicker
|
||||
=> _isGameRunning && AppHost.Device.VSyncMode == VSyncMode.Custom;
|
||||
|
||||
public void UpdateVSyncIntervalPicker()
|
||||
{
|
||||
get => _loadHeading;
|
||||
set
|
||||
{
|
||||
_loadHeading = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string CacheLoadStatus
|
||||
{
|
||||
get => _cacheLoadStatus;
|
||||
set
|
||||
{
|
||||
_cacheLoadStatus = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Brush ProgressBarBackgroundColor
|
||||
{
|
||||
get => _progressBarBackgroundColor;
|
||||
set
|
||||
{
|
||||
_progressBarBackgroundColor = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Brush ProgressBarForegroundColor
|
||||
{
|
||||
get => _progressBarForegroundColor;
|
||||
set
|
||||
{
|
||||
_progressBarForegroundColor = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Brush VSyncModeColor
|
||||
{
|
||||
get => _vSyncModeColor;
|
||||
set
|
||||
{
|
||||
_vSyncModeColor = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowCustomVSyncIntervalPicker
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isGameRunning)
|
||||
{
|
||||
return AppHost.Device.VSyncMode ==
|
||||
VSyncMode.Custom;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
OnPropertyChanged();
|
||||
}
|
||||
OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
|
||||
}
|
||||
|
||||
public int CustomVSyncIntervalPercentageProxy
|
||||
@@ -551,126 +411,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] SelectedIcon
|
||||
{
|
||||
get => _selectedIcon;
|
||||
set
|
||||
{
|
||||
_selectedIcon = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int ProgressMaximum
|
||||
{
|
||||
get => _progressMaximum;
|
||||
set
|
||||
{
|
||||
_progressMaximum = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int ProgressValue
|
||||
{
|
||||
get => _progressValue;
|
||||
set
|
||||
{
|
||||
_progressValue = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int StatusBarProgressMaximum
|
||||
{
|
||||
get => _statusBarProgressMaximum;
|
||||
set
|
||||
{
|
||||
_statusBarProgressMaximum = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int StatusBarProgressValue
|
||||
{
|
||||
get => _statusBarProgressValue;
|
||||
set
|
||||
{
|
||||
_statusBarProgressValue = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool StatusBarProgressStatusVisible
|
||||
{
|
||||
get => _statusBarProgressStatusVisible;
|
||||
set
|
||||
{
|
||||
_statusBarProgressStatusVisible = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string StatusBarProgressStatusText
|
||||
{
|
||||
get => _statusBarProgressStatusText;
|
||||
set
|
||||
{
|
||||
_statusBarProgressStatusText = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string FifoStatusText
|
||||
{
|
||||
get => _fifoStatusText;
|
||||
set
|
||||
{
|
||||
_fifoStatusText = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string GpuNameText
|
||||
{
|
||||
get => _gpuStatusText;
|
||||
set
|
||||
{
|
||||
_gpuStatusText = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string ShaderCountText
|
||||
{
|
||||
get => _shaderCountText;
|
||||
set
|
||||
{
|
||||
_shaderCountText = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string BackendText
|
||||
{
|
||||
get => _backendText;
|
||||
set
|
||||
{
|
||||
_backendText = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string VSyncModeText
|
||||
{
|
||||
get => _vSyncModeText;
|
||||
@@ -679,39 +419,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
_vSyncModeText = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string DockedStatusText
|
||||
{
|
||||
get => _dockedStatusText;
|
||||
set
|
||||
{
|
||||
_dockedStatusText = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string AspectRatioStatusText
|
||||
{
|
||||
get => _aspectStatusText;
|
||||
set
|
||||
{
|
||||
_aspectStatusText = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string VolumeStatusText
|
||||
{
|
||||
get => _volumeStatusText;
|
||||
set
|
||||
{
|
||||
_volumeStatusText = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,73 +443,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public float VolumeBeforeMute
|
||||
{
|
||||
get => _volumeBeforeMute;
|
||||
set
|
||||
{
|
||||
_volumeBeforeMute = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowStatusSeparator
|
||||
{
|
||||
get => _showStatusSeparator;
|
||||
set
|
||||
{
|
||||
_showStatusSeparator = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowMenuAndStatusBar
|
||||
{
|
||||
get => _showMenuAndStatusBar;
|
||||
set
|
||||
{
|
||||
_showMenuAndStatusBar = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsLoadingIndeterminate
|
||||
{
|
||||
get => _isLoadingIndeterminate;
|
||||
set
|
||||
{
|
||||
_isLoadingIndeterminate = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsActive
|
||||
{
|
||||
get => _isActive;
|
||||
set
|
||||
{
|
||||
_isActive = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool ShowContent
|
||||
{
|
||||
get => _showContent;
|
||||
set
|
||||
{
|
||||
_showContent = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAppletMenuActive
|
||||
{
|
||||
get => _isAppletMenuActive && EnableNonGameRunningControls;
|
||||
@@ -813,39 +454,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public WindowState WindowState
|
||||
{
|
||||
get => _windowState;
|
||||
internal set
|
||||
{
|
||||
_windowState = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public double WindowWidth
|
||||
{
|
||||
get => _windowWidth;
|
||||
set
|
||||
{
|
||||
_windowWidth = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public double WindowHeight
|
||||
{
|
||||
get => _windowHeight;
|
||||
set
|
||||
{
|
||||
_windowHeight = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsGrid => Glyph == Glyph.Grid;
|
||||
public bool IsList => Glyph == Glyph.List;
|
||||
|
||||
@@ -889,17 +497,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => _title;
|
||||
set
|
||||
{
|
||||
_title = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowConsoleVisible
|
||||
{
|
||||
get => ConsoleHelper.SetConsoleWindowStateSupported;
|
||||
@@ -910,27 +507,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
get => FileAssociationHelper.IsTypeAssociationSupported;
|
||||
}
|
||||
|
||||
public bool AreMimeTypesRegistered
|
||||
{
|
||||
get => _areMimeTypesRegistered;
|
||||
set {
|
||||
_areMimeTypesRegistered = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollectionExtended<ApplicationData> Applications
|
||||
{
|
||||
get => _applications;
|
||||
set
|
||||
{
|
||||
_applications = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Glyph Glyph
|
||||
{
|
||||
get => (Glyph)ConfigurationState.Instance.UI.GameListViewMode.Value;
|
||||
@@ -948,7 +524,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public bool ShowNames
|
||||
{
|
||||
get => ConfigurationState.Instance.UI.ShowNames && ConfigurationState.Instance.UI.GridSize > 1; set
|
||||
get => ConfigurationState.Instance.UI.ShowNames && ConfigurationState.Instance.UI.GridSize > 1;
|
||||
set
|
||||
{
|
||||
ConfigurationState.Instance.UI.ShowNames.Value = value;
|
||||
|
||||
@@ -1508,8 +1085,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
|
||||
VSyncModeText = args.VSyncMode == "Custom" ? "Custom" : "VSync";
|
||||
ShowCustomVSyncIntervalPicker =
|
||||
args.VSyncMode == VSyncMode.Custom.ToString();
|
||||
DockedStatusText = args.DockedMode;
|
||||
AspectRatioStatusText = args.AspectRatio;
|
||||
GameStatusText = args.GameStatus;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using DynamicData;
|
||||
using Gommon;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
@@ -18,13 +17,13 @@ using System.Linq;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
public class ModManagerViewModel : BaseModel
|
||||
public partial class ModManagerViewModel : BaseModel
|
||||
{
|
||||
private readonly string _modJsonPath;
|
||||
|
||||
private AvaloniaList<ModModel> _mods = new();
|
||||
private AvaloniaList<ModModel> _views = new();
|
||||
private AvaloniaList<ModModel> _selectedMods = new();
|
||||
[ObservableProperty] private AvaloniaList<ModModel> _views = new();
|
||||
[ObservableProperty] private AvaloniaList<ModModel> _selectedMods = new();
|
||||
|
||||
private string _search;
|
||||
private readonly ulong _applicationId;
|
||||
@@ -44,26 +43,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public AvaloniaList<ModModel> Views
|
||||
{
|
||||
get => _views;
|
||||
set
|
||||
{
|
||||
_views = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public AvaloniaList<ModModel> SelectedMods
|
||||
{
|
||||
get => _selectedMods;
|
||||
set
|
||||
{
|
||||
_selectedMods = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
@@ -86,10 +65,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
_modJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationId.ToString("x16"), "mods.json");
|
||||
|
||||
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
_storageProvider = desktop.MainWindow.StorageProvider;
|
||||
}
|
||||
_storageProvider = RyujinxApp.MainWindow.StorageProvider;
|
||||
|
||||
LoadMods(applicationId);
|
||||
}
|
||||
@@ -146,8 +122,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
.Filter(Filter)
|
||||
.Bind(out var view).AsObservableList();
|
||||
|
||||
#pragma warning disable MVVMTK0034 // Event to update is fired below
|
||||
_views.Clear();
|
||||
_views.AddRange(view);
|
||||
#pragma warning restore MVVMTK0034
|
||||
|
||||
SelectedMods = new(Views.Where(x => x.Enabled));
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using Gommon;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Gommon;
|
||||
using Ryujinx.Ava.Utilities.Configuration;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
public class SettingsHacksViewModel : BaseModel
|
||||
public partial class SettingsHacksViewModel : BaseModel
|
||||
{
|
||||
private readonly SettingsViewModel _baseViewModel;
|
||||
|
||||
@@ -14,33 +15,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
_baseViewModel = settingsVm;
|
||||
}
|
||||
|
||||
private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix;
|
||||
private bool _shaderTranslationThreadSleep = ConfigurationState.Instance.Hacks.EnableShaderTranslationDelay;
|
||||
[ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix;
|
||||
[ObservableProperty] private bool _shaderTranslationDelayEnabled = ConfigurationState.Instance.Hacks.EnableShaderTranslationDelay;
|
||||
private int _shaderTranslationSleepDelay = ConfigurationState.Instance.Hacks.ShaderTranslationDelay;
|
||||
|
||||
public bool Xc2MenuSoftlockFixEnabled
|
||||
{
|
||||
get => _xc2MenuSoftlockFix;
|
||||
set
|
||||
{
|
||||
_xc2MenuSoftlockFix = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShaderTranslationDelayEnabled
|
||||
{
|
||||
get => _shaderTranslationThreadSleep;
|
||||
set
|
||||
{
|
||||
_shaderTranslationThreadSleep = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string ShaderTranslationDelayTooltipText => $"Current value: {ShaderTranslationDelay}";
|
||||
public string ShaderTranslationDelayValueText => $"{ShaderTranslationDelay}ms";
|
||||
|
||||
public int ShaderTranslationDelay
|
||||
{
|
||||
@@ -49,7 +28,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
_shaderTranslationSleepDelay = value;
|
||||
|
||||
OnPropertiesChanged(nameof(ShaderTranslationDelay), nameof(ShaderTranslationDelayTooltipText));
|
||||
OnPropertiesChanged(nameof(ShaderTranslationDelay), nameof(ShaderTranslationDelayValueText));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -466,11 +466,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public void MatchSystemTime()
|
||||
{
|
||||
var dto = DateTimeOffset.Now;
|
||||
|
||||
CurrentDate = new DateTimeOffset(dto.Year, dto.Month, dto.Day, 0, 0, 0, dto.Offset);
|
||||
(DateTimeOffset dto, TimeSpan timeOfDay) = DateTimeOffset.Now.Extract();
|
||||
|
||||
CurrentTime = dto.TimeOfDay;
|
||||
CurrentDate = dto;
|
||||
CurrentTime = timeOfDay;
|
||||
|
||||
OnPropertyChanged(nameof(CurrentDate));
|
||||
OnPropertyChanged(nameof(CurrentTime));
|
||||
@@ -756,7 +755,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
config.Multiplayer.LdnServer.Value = LdnServer;
|
||||
|
||||
// Dirty Hacks
|
||||
config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFixEnabled;
|
||||
config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix;
|
||||
config.Hacks.EnableShaderTranslationDelay.Value = DirtyHacks.ShaderTranslationDelayEnabled;
|
||||
config.Hacks.ShaderTranslationDelay.Value = DirtyHacks.ShaderTranslationDelay;
|
||||
|
||||
|
||||
@@ -1,74 +1,32 @@
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Common.Models;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Application = Avalonia.Application;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
public record TitleUpdateViewNoUpdateSentinal();
|
||||
public record TitleUpdateViewModelNoUpdate;
|
||||
|
||||
public class TitleUpdateViewModel : BaseModel
|
||||
public partial class TitleUpdateViewModel : BaseModel
|
||||
{
|
||||
private ApplicationLibrary ApplicationLibrary { get; }
|
||||
private ApplicationData ApplicationData { get; }
|
||||
|
||||
private AvaloniaList<TitleUpdateModel> _titleUpdates = new();
|
||||
private AvaloniaList<object> _views = new();
|
||||
private object _selectedUpdate = new TitleUpdateViewNoUpdateSentinal();
|
||||
private bool _showBundledContentNotice = false;
|
||||
[ObservableProperty] private AvaloniaList<TitleUpdateModel> _titleUpdates = new();
|
||||
[ObservableProperty] private AvaloniaList<object> _views = new();
|
||||
[ObservableProperty] private object _selectedUpdate = new TitleUpdateViewModelNoUpdate();
|
||||
[ObservableProperty] private bool _showBundledContentNotice;
|
||||
|
||||
public AvaloniaList<TitleUpdateModel> TitleUpdates
|
||||
{
|
||||
get => _titleUpdates;
|
||||
set
|
||||
{
|
||||
_titleUpdates = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public AvaloniaList<object> Views
|
||||
{
|
||||
get => _views;
|
||||
set
|
||||
{
|
||||
_views = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public object SelectedUpdate
|
||||
{
|
||||
get => _selectedUpdate;
|
||||
set
|
||||
{
|
||||
_selectedUpdate = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowBundledContentNotice
|
||||
{
|
||||
get => _showBundledContentNotice;
|
||||
set
|
||||
{
|
||||
_showBundledContentNotice = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public IStorageProvider StorageProvider;
|
||||
private readonly IStorageProvider _storageProvider;
|
||||
|
||||
public TitleUpdateViewModel(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
||||
{
|
||||
@@ -76,10 +34,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
ApplicationData = applicationData;
|
||||
|
||||
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
StorageProvider = desktop.MainWindow.StorageProvider;
|
||||
}
|
||||
_storageProvider = RyujinxApp.MainWindow.StorageProvider;
|
||||
|
||||
LoadUpdates();
|
||||
}
|
||||
@@ -90,7 +45,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
.Where(it => it.TitleUpdate.TitleIdBase == ApplicationData.IdBase);
|
||||
|
||||
bool hasBundledContent = false;
|
||||
SelectedUpdate = new TitleUpdateViewNoUpdateSentinal();
|
||||
SelectedUpdate = new TitleUpdateViewModelNoUpdate();
|
||||
foreach ((TitleUpdateModel update, bool isSelected) in updates)
|
||||
{
|
||||
TitleUpdates.Add(update);
|
||||
@@ -116,12 +71,12 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
var selected = SelectedUpdate;
|
||||
|
||||
Views.Clear();
|
||||
Views.Add(new TitleUpdateViewNoUpdateSentinal());
|
||||
Views.Add(new TitleUpdateViewModelNoUpdate());
|
||||
Views.AddRange(sortedUpdates);
|
||||
|
||||
SelectedUpdate = selected;
|
||||
|
||||
if (SelectedUpdate is TitleUpdateViewNoUpdateSentinal)
|
||||
if (SelectedUpdate is TitleUpdateViewModelNoUpdate)
|
||||
{
|
||||
SelectedUpdate = Views[0];
|
||||
}
|
||||
@@ -179,7 +134,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
else if (update == SelectedUpdate as TitleUpdateModel)
|
||||
{
|
||||
SelectedUpdate = new TitleUpdateViewNoUpdateSentinal();
|
||||
SelectedUpdate = new TitleUpdateViewModelNoUpdate();
|
||||
}
|
||||
|
||||
SortUpdates();
|
||||
@@ -187,7 +142,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public async Task Add()
|
||||
{
|
||||
var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
var result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = true,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Avalonia.Media;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
@@ -20,12 +21,12 @@ using Image = SkiaSharp.SKImage;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
internal class UserFirmwareAvatarSelectorViewModel : BaseModel
|
||||
internal partial class UserFirmwareAvatarSelectorViewModel : BaseModel
|
||||
{
|
||||
private static readonly Dictionary<string, byte[]> _avatarStore = new();
|
||||
|
||||
private ObservableCollection<ProfileImageModel> _images;
|
||||
private Color _backgroundColor = Colors.White;
|
||||
[ObservableProperty] private ObservableCollection<ProfileImageModel> _images;
|
||||
[ObservableProperty] private Color _backgroundColor = Colors.White;
|
||||
|
||||
private int _selectedIndex;
|
||||
|
||||
@@ -34,27 +35,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
_images = new ObservableCollection<ProfileImageModel>();
|
||||
|
||||
LoadImagesFromStore();
|
||||
}
|
||||
|
||||
public Color BackgroundColor
|
||||
{
|
||||
get => _backgroundColor;
|
||||
set
|
||||
PropertyChanged += (_, args) =>
|
||||
{
|
||||
_backgroundColor = value;
|
||||
OnPropertyChanged();
|
||||
ChangeImageBackground();
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<ProfileImageModel> Images
|
||||
{
|
||||
get => _images;
|
||||
set
|
||||
{
|
||||
_images = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
if (args.PropertyName == nameof(BackgroundColor))
|
||||
ChangeImageBackground();
|
||||
};
|
||||
}
|
||||
|
||||
public int SelectedIndex
|
||||
@@ -70,7 +55,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedImage = _images[_selectedIndex].Data;
|
||||
SelectedImage = Images[_selectedIndex].Data;
|
||||
}
|
||||
|
||||
OnPropertyChanged();
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
internal class UserProfileImageSelectorViewModel : BaseModel
|
||||
internal partial class UserProfileImageSelectorViewModel : BaseModel
|
||||
{
|
||||
private bool _firmwareFound;
|
||||
|
||||
public bool FirmwareFound
|
||||
{
|
||||
get => _firmwareFound;
|
||||
|
||||
set
|
||||
{
|
||||
_firmwareFound = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
[ObservableProperty] private bool _firmwareFound;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using DynamicData;
|
||||
using DynamicData.Binding;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
@@ -8,74 +9,31 @@ using System.Collections.ObjectModel;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
public class UserSaveManagerViewModel : BaseModel
|
||||
public partial class UserSaveManagerViewModel : BaseModel
|
||||
{
|
||||
private int _sortIndex;
|
||||
private int _orderIndex;
|
||||
private string _search;
|
||||
private ObservableCollection<SaveModel> _saves = new();
|
||||
private ObservableCollection<SaveModel> _views = new();
|
||||
[ObservableProperty] private int _sortIndex;
|
||||
[ObservableProperty] private int _orderIndex;
|
||||
[ObservableProperty] private string _search;
|
||||
[ObservableProperty] private ObservableCollection<SaveModel> _saves = new();
|
||||
[ObservableProperty] private ObservableCollection<SaveModel> _views = new();
|
||||
private readonly AccountManager _accountManager;
|
||||
|
||||
public string SaveManagerHeading => LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SaveManagerHeading, _accountManager.LastOpenedUser.Name, _accountManager.LastOpenedUser.UserId);
|
||||
|
||||
public int SortIndex
|
||||
{
|
||||
get => _sortIndex;
|
||||
set
|
||||
{
|
||||
_sortIndex = value;
|
||||
OnPropertyChanged();
|
||||
Sort();
|
||||
}
|
||||
}
|
||||
|
||||
public int OrderIndex
|
||||
{
|
||||
get => _orderIndex;
|
||||
set
|
||||
{
|
||||
_orderIndex = value;
|
||||
OnPropertyChanged();
|
||||
Sort();
|
||||
}
|
||||
}
|
||||
|
||||
public string Search
|
||||
{
|
||||
get => _search;
|
||||
set
|
||||
{
|
||||
_search = value;
|
||||
OnPropertyChanged();
|
||||
Sort();
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<SaveModel> Saves
|
||||
{
|
||||
get => _saves;
|
||||
set
|
||||
{
|
||||
_saves = value;
|
||||
OnPropertyChanged();
|
||||
Sort();
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<SaveModel> Views
|
||||
{
|
||||
get => _views;
|
||||
set
|
||||
{
|
||||
_views = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public UserSaveManagerViewModel(AccountManager accountManager)
|
||||
{
|
||||
_accountManager = accountManager;
|
||||
PropertyChanged += (_, evt) =>
|
||||
{
|
||||
if (evt.PropertyName is
|
||||
nameof(SortIndex) or
|
||||
nameof(OrderIndex) or
|
||||
nameof(Search) or
|
||||
nameof(Saves))
|
||||
{
|
||||
Sort();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void Sort()
|
||||
@@ -85,8 +43,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
.Sort(GetComparer())
|
||||
.Bind(out var view).AsObservableList();
|
||||
|
||||
#pragma warning disable MVVMTK0034
|
||||
_views.Clear();
|
||||
_views.AddRange(view);
|
||||
#pragma warning restore MVVMTK0034
|
||||
OnPropertyChanged(nameof(Views));
|
||||
}
|
||||
|
||||
@@ -94,7 +54,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
if (arg is SaveModel save)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(_search) || save.Title.ToLower().Contains(_search.ToLower());
|
||||
return string.IsNullOrWhiteSpace(Search) || save.Title.ToLower().Contains(Search.ToLower());
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
private void VSyncMode_PointerReleased(object sender, PointerReleasedEventArgs e)
|
||||
{
|
||||
Window.ViewModel.ToggleVSyncMode();
|
||||
Logger.Info?.Print(LogClass.Application, $"VSync Mode toggled to: {Window.ViewModel.AppHost.Device.VSyncMode}");
|
||||
Logger.Info?.PrintMsg(LogClass.Application, $"VSync Mode toggled to: {Window.ViewModel.AppHost.Device.VSyncMode}");
|
||||
}
|
||||
|
||||
private void DockedStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
ToolTip.Tip="{Binding DirtyHacks.Xc2MenuFixTooltip}">
|
||||
<CheckBox
|
||||
Margin="0"
|
||||
IsChecked="{Binding DirtyHacks.Xc2MenuSoftlockFixEnabled}"/>
|
||||
IsChecked="{Binding DirtyHacks.Xc2MenuSoftlockFix}"/>
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
Text="Xenoblade Chronicles 2 Menu Softlock Fix" />
|
||||
@@ -54,21 +54,27 @@
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
Text="Arbitrary Delay on Shader Translation"/>
|
||||
</StackPanel>
|
||||
<Slider IsVisible="{Binding DirtyHacks.ShaderTranslationDelayEnabled}"
|
||||
HorizontalAlignment="Center"
|
||||
Value="{Binding DirtyHacks.ShaderTranslationDelay}"
|
||||
ToolTip.Tip="{Binding DirtyHacks.ShaderTranslationDelayTooltipText}"
|
||||
Width="175"
|
||||
Margin="0,-3,0,0"
|
||||
Height="32"
|
||||
Padding="0,-5"
|
||||
TickFrequency="1"
|
||||
IsSnapToTickEnabled="True"
|
||||
LargeChange="10"
|
||||
SmallChange="1"
|
||||
VerticalAlignment="Center"
|
||||
Minimum="1"
|
||||
Maximum="1000" />
|
||||
<StackPanel
|
||||
IsVisible="{Binding DirtyHacks.ShaderTranslationDelayEnabled}"
|
||||
Margin="0,10,0,0"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Center">
|
||||
<Slider HorizontalAlignment="Center"
|
||||
Value="{Binding DirtyHacks.ShaderTranslationDelay}"
|
||||
Width="175"
|
||||
Margin="0,-3,0,0"
|
||||
Height="32"
|
||||
Padding="0,-5"
|
||||
TickFrequency="1"
|
||||
IsSnapToTickEnabled="True"
|
||||
LargeChange="10"
|
||||
SmallChange="1"
|
||||
VerticalAlignment="Center"
|
||||
Minimum="1"
|
||||
Maximum="1000" />
|
||||
<TextBlock Margin="5,0"
|
||||
Text="{Binding DirtyHacks.ShaderTranslationDelayValueText}"/>
|
||||
</StackPanel>
|
||||
<Separator/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
Padding="10"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
ToolTip.Tip="{Binding Path}"
|
||||
Click="OpenLocation">
|
||||
<ui:SymbolIcon
|
||||
Symbol="OpenFolder"
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
<DataTemplate
|
||||
DataType="viewModels:TitleUpdateViewNoUpdateSentinal">
|
||||
DataType="viewModels:TitleUpdateViewModelNoUpdate">
|
||||
<Panel
|
||||
Height="33"
|
||||
Margin="10">
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
||||
public string Path { get; set; }
|
||||
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
|
||||
|
||||
public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0;
|
||||
public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0 && !ControlHolder.ByteSpan.IsZeros();
|
||||
|
||||
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
public MemoryManagerMode MemoryManagerMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Expands the RAM amount on the emulated system from 4GiB to 8GiB
|
||||
/// Expands the RAM amount on the emulated system
|
||||
/// </summary>
|
||||
public MemoryConfiguration DramSize { get; set; }
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -645,6 +645,9 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
|
||||
private void HackChanged(object sender, ReactiveEventArgs<bool> rxe)
|
||||
{
|
||||
if (!ShowDirtyHacks)
|
||||
return;
|
||||
|
||||
var newHacks = EnabledHacks.Select(x => x.Hack)
|
||||
.JoinToString(", ");
|
||||
|
||||
@@ -666,14 +669,14 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||
List<EnabledDirtyHack> enabledHacks = [];
|
||||
|
||||
if (Xc2MenuSoftlockFix)
|
||||
Apply(DirtyHacks.Xc2MenuSoftlockFix);
|
||||
Apply(DirtyHack.Xc2MenuSoftlockFix);
|
||||
|
||||
if (EnableShaderTranslationDelay)
|
||||
Apply(DirtyHacks.ShaderCompilationThreadSleep, ShaderTranslationDelay);
|
||||
Apply(DirtyHack.ShaderTranslationDelay, ShaderTranslationDelay);
|
||||
|
||||
return enabledHacks.ToArray();
|
||||
|
||||
void Apply(DirtyHacks hack, int value = 0)
|
||||
void Apply(DirtyHack hack, int value = 0)
|
||||
{
|
||||
enabledHacks.Add(new EnabledDirtyHack(hack, value));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user