Compare commits

..

15 Commits

Author SHA1 Message Date
Evan Husted
023bd5f00f UI: Enable Rainbow cycling in the Settings window 2025-01-29 20:27:01 -06:00
Evan Husted
0ed7fd14ba misc: chore: [ci skip] Collapse CheckboxMenuItemStyle into the main Styles.xaml. 2025-01-29 18:59:17 -06:00
Evan Husted
a624fe64b9 UI: Scanning for mods on DLC content 2025-01-29 13:33:34 -06:00
Vladimir Sokolov
e02ef52069 Added --backend-threading arg for CommandLineState (#599)
Added the `--backend-threading` arg so that you can launch games via
a shortcut with modifications to this setting.
2025-01-29 12:49:36 -06:00
Evan Husted
707c9ef748 misc: chore: slightly improve PTC init log line 2025-01-28 22:25:01 -06:00
Evan Husted
2acc43e968 misc: chore: Use string.Empty in more places where it's snuck back 2025-01-28 22:17:11 -06:00
Evan Husted
191e158289 misc: chore: Use static instances of converters instead of using control resources 2025-01-28 22:11:48 -06:00
Evan Husted
a469f3d710 UI: Remove empty StackPanel in UserSelectorDialog 2025-01-28 21:47:29 -06:00
shinyoyo
1b3656bca9 LED Color & LED settings header (zh_CN) (#590) 2025-01-28 21:29:06 -06:00
Evan Husted
502ce98b3a UI: [ci skip] Make cheat window larger by default 2025-01-28 21:27:51 -06:00
LotP1
7085bafa60 PPTC Profiles (#370)
Added functionality that allows ExeFS mods to compile to their own PPTC
Profile and therefore store PTC data between sessions.
The feature calculates the hash of the currently loaded ExeFS mods and
stores the PPTC data in a profile that matches said hash, so you can
have multiple ExeFS loadouts without causing issues. This includes
different versions of the same mod as their hashes will be different.
Using this PR should be seamless as the JIT Sparse PR already laid the
groundwork for PPTC Profiles and this PR just allows ExeFS mods to load
and store their own profiles besides the `default` profile.

 **WARNING!** 
**This will update your PPTC profile version, which means the
PPTC profile will be invalidated if you try to run a PR/Build/Branch
that does not include this change!**
**This is only relevant for the default PPTC Profile, as any other profiles do not exist to older versions!**
2025-01-28 20:36:58 -06:00
Evan Husted
9d28af935d headless: Enable Rainbow cycling if any input configs have UseRainbow enabled 2025-01-28 20:16:41 -06:00
Evan Husted
cdf4016c25 Update README.md 2025-01-27 15:04:57 -06:00
Evan Husted
082c718f5d fix canary URL 2025-01-27 15:04:14 -06:00
Josh
31de0bf8c6 Increase NAT discovery timeout to 5000ms (#589)
1000ms was too fast on some slower networks. It would lead to an early
cancellation before device could be found.
2025-01-26 19:40:10 -06:00
52 changed files with 225 additions and 212 deletions

View File

@@ -11,7 +11,7 @@
[![Latest release](https://img.shields.io/github/v/release/GreemDev/Ryujinx)](https://github.com/Ryubing/Ryujinx/releases/latest)
<br>
[![Canary workflow](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml/badge.svg)](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml)
[![Latest canary release](https://img.shields.io/github/v/release/GreemDev/Ryujinx-Canary?label=canary)](https://github.com/Ryubing/Ryujinx-Canary/releases/latest)
[![Latest canary release](https://img.shields.io/github/v/release/Ryubing/Canary-Releases?label=canary)](https://github.com/Ryubing/Canary-Releases/releases/latest)
</td>
</tr>
</table>
@@ -64,7 +64,7 @@ Canary builds are compiled automatically for each commit on the `master` branch.
While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
These canary builds are only recommended for experienced users.
You can find the latest canary release [here](https://github.com/Ryubing/Ryujinx-Canary/releases/latest).
You can find the latest canary release [here](https://github.com/Ryubing/Canary-Releases/releases/latest).
## Documentation

View File

@@ -4,6 +4,7 @@ using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Common;
using ARMeilleure.Memory;
using ARMeilleure.State;
using Humanizer;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
@@ -923,15 +924,11 @@ namespace ARMeilleure.Translation.PTC
sw.Stop();
PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount);
if (_translateCount == _translateTotalCount)
{
Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s");
}
else
{
Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | {_translateTotalCount - _translateCount} function{(_translateTotalCount - _translateCount != 1 ? "s" : "")} blacklisted | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s");
}
Logger.Info?.Print(LogClass.Ptc,
$"{_translateCount} of {_translateTotalCount} functions translated in {sw.Elapsed.TotalSeconds} seconds " +
$"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " +
$"| Thread count: {degreeOfParallelism}");
Thread preSaveThread = new(PreSave)
{

View File

@@ -76,7 +76,7 @@ namespace Ryujinx.Graphics.Metal
return model;
}
return "";
return string.Empty;
}
}
}

View File

@@ -218,7 +218,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
foreach (MemoryDefinition memory in memories)
{
string arraySize = "";
string arraySize = string.Empty;
if ((memory.Type & AggregateType.Array) != 0)
{
arraySize = $"[{memory.ArrayLength}]";
@@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
BufferDefinition buffer = buffers[i];
bool needsPadding = buffer.Layout == BufferLayout.Std140;
string fsiSuffix = !constant && fsi ? " [[raster_order_group(0)]]" : "";
string fsiSuffix = !constant && fsi ? " [[raster_order_group(0)]]" : string.Empty;
bufferDec[i] = $"{addressSpace} {Defaults.StructPrefix}_{buffer.Name}* {buffer.Name}{fsiSuffix};";
@@ -257,7 +257,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
type &= ~AggregateType.Array;
string typeName = GetVarTypeName(type);
string arraySuffix = "";
string arraySuffix = string.Empty;
if (field.Type.HasFlag(AggregateType.Array))
{
@@ -353,7 +353,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
imageTypeName = $"array<{imageTypeName}, {image.ArrayLength}>";
}
string fsiSuffix = fsi ? " [[raster_order_group(0)]]" : "";
string fsiSuffix = fsi ? " [[raster_order_group(0)]]" : string.Empty;
imageDec[i] = $"{imageTypeName} {image.Name}{fsiSuffix};";
}
@@ -454,7 +454,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
IoVariable.VertexIndex => "[[vertex_id]]",
// IoVariable.PointCoord => "[[point_coord]]",
IoVariable.UserDefined => context.Definitions.Stage == ShaderStage.Fragment ? $"[[user(loc{ioDefinition.Location})]]" : $"[[attribute({ioDefinition.Location})]]",
_ => ""
_ => string.Empty
};
context.AppendLine($"{type} {name} {iq}{suffix};");
@@ -545,7 +545,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
IoVariable.FragmentOutputColor => $"[[color({ioDefinition.Location})]]",
IoVariable.FragmentOutputDepth => "[[depth(any)]]",
IoVariable.ClipDistance => $"[[clip_distance]][{Defaults.TotalClipDistances}]",
_ => ""
_ => string.Empty
};
context.AppendLine($"{type} {name} {suffix};");

View File

@@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
inputsCount--;
}
string fieldName = "";
string fieldName = string.Empty;
switch (storageKind)
{
case StorageKind.ConstantBuffer:
@@ -140,7 +140,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
}
}
varName += fieldName;
varName += fieldHasPadding ? ".x" : "";
varName += fieldHasPadding ? ".x" : string.Empty;
if (isStore)
{
@@ -434,7 +434,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
string prefix = intCoords ? "uint" : "float";
return prefix + (count > 1 ? count : "") + "(" + coords + ")";
return prefix + (count > 1 ? count : string.Empty) + "(" + coords + ")";
}
Append(AssemblePVector(pCount));
@@ -504,7 +504,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
}
texCallBuilder.Append(')');
texCallBuilder.Append(colorIsVector ? GetMaskMultiDest(texOp.Index) : "");
texCallBuilder.Append(colorIsVector ? GetMaskMultiDest(texOp.Index) : string.Empty);
return texCallBuilder.ToString();
}
@@ -558,7 +558,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
{
if (mask == 0x0)
{
return "";
return string.Empty;
}
string swizzle = ".";

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
if (parameters.Definitions.Stage is not (ShaderStage.Vertex or ShaderStage.Fragment or ShaderStage.Compute))
{
Logger.Warning?.Print(LogClass.Gpu, $"Attempted to generate unsupported shader type {parameters.Definitions.Stage}!");
return "";
return string.Empty;
}
CodeGenContext context = new(info, parameters);

View File

@@ -199,7 +199,7 @@ namespace Ryujinx.Graphics.Shader
_ => "float"
};
return $"{typeName}<{format}{(image ? ", access::read_write" : "")}>";
return $"{typeName}<{format}{(image ? ", access::read_write" : string.Empty)}>";
}
}
}

View File

@@ -192,6 +192,7 @@ namespace Ryujinx.HLE
/// <summary>
/// The desired hacky workarounds.
/// </summary>
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
public EnabledDirtyHack[] Hacks { internal get; set; }
public HLEConfiguration(VirtualFileSystem virtualFileSystem,

View File

@@ -296,7 +296,7 @@ namespace Ryujinx.HLE.HOS
AddModsFromDirectory(mods, applicationDir, modMetadata);
}
public static void QueryContentsDir(ModCache mods, DirectoryInfo contentsDir, ulong applicationId)
public static void QueryContentsDir(ModCache mods, DirectoryInfo contentsDir, ulong applicationId, ulong[] installedDlcs)
{
if (!contentsDir.Exists)
{
@@ -311,6 +311,16 @@ namespace Ryujinx.HLE.HOS
{
QueryApplicationDir(mods, applicationDir, applicationId);
}
foreach (ulong installedDlcId in installedDlcs)
{
DirectoryInfo dlcModDir = FindApplicationDir(contentsDir, $"{installedDlcId:x16}");
if (dlcModDir != null)
{
QueryApplicationDir(mods, dlcModDir, applicationId);
}
}
}
private static int QueryCheatsDir(ModCache mods, DirectoryInfo cheatsDir)
@@ -417,7 +427,7 @@ namespace Ryujinx.HLE.HOS
{
foreach ((ulong applicationId, ModCache cache) in modCaches)
{
QueryContentsDir(cache, searchDir, applicationId);
QueryContentsDir(cache, searchDir, applicationId, Array.Empty<ulong>());
}
return true;
@@ -679,7 +689,7 @@ namespace Ryujinx.HLE.HOS
{
using (MD5 md5 = MD5.Create())
{
modLoadResult.Hash += BitConverter.ToString(md5.ComputeHash(tempHash.ToBytes())).Replace("-", "").ToLowerInvariant();
modLoadResult.Hash += BitConverter.ToString(md5.ComputeHash(tempHash.ToBytes())).Replace("-", string.Empty).ToLowerInvariant();
}
}

View File

@@ -121,7 +121,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu
private void UpdatePassphraseIfNeeded()
{
string passphrase = _config.MultiplayerLdnPassphrase ?? "";
string passphrase = _config.MultiplayerLdnPassphrase ?? string.Empty;
if (passphrase != _passphrase)
{
_passphrase = passphrase;

View File

@@ -113,7 +113,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu.Proxy
public async Task<ushort> NatPunch()
{
NatDiscoverer discoverer = new();
CancellationTokenSource cts = new(1000);
CancellationTokenSource cts = new(5000);
NatDevice device;

View File

@@ -88,7 +88,7 @@ namespace Ryujinx.HLE.Loaders.Processes
bool isFirmwareApplication = ProgramId <= 0x0100000000007FFF;
string name = !isFirmware
? (isFirmwareApplication ? "Firmware Application " : "") + (!string.IsNullOrWhiteSpace(Name) ? Name : "<Unknown Name>")
? (isFirmwareApplication ? "Firmware Application " : string.Empty) + (!string.IsNullOrWhiteSpace(Name) ? Name : "<Unknown Name>")
: "Firmware";
// TODO: LibHac npdm currently doesn't support version field.

View File

@@ -2,8 +2,6 @@ using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS.Services.Hid;
using SDL2;
using System;
using System.Collections.Generic;
using System.Numerics;
@@ -12,7 +10,7 @@ using static SDL2.SDL;
namespace Ryujinx.Input.SDL2
{
class SDL2Gamepad : IGamepad
public class SDL2Gamepad : IGamepad
{
private bool HasConfiguration => _configuration != null;

View File

@@ -1,13 +0,0 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="MenuItem.withCheckbox Viewbox#PART_IconPresenter">
<Setter Property="MaxHeight" Value="36" />
<Setter Property="MinHeight" Value="36" />
<Setter Property="MaxWidth" Value="36" />
<Setter Property="MinWidth" Value="36" />
</Style>
<Style Selector="MenuItem.withCheckbox ContentPresenter#PART_HeaderPresenter">
<Setter Property="Padding" Value="-10,0,0,0" />
</Style>
</Styles>

View File

@@ -218,6 +218,15 @@
<Setter Property="BorderBrush"
Value="{DynamicResource ThemeControlBorderColor}" />
</Style>
<Style Selector="MenuItem.withCheckbox Viewbox#PART_IconPresenter">
<Setter Property="MaxHeight" Value="36" />
<Setter Property="MinHeight" Value="36" />
<Setter Property="MaxWidth" Value="36" />
<Setter Property="MinWidth" Value="36" />
</Style>
<Style Selector="MenuItem.withCheckbox ContentPresenter#PART_HeaderPresenter">
<Setter Property="Padding" Value="-10,0,0,0" />
</Style>
<Style Selector="TabItem > ScrollViewer">
<Setter Property="Background"
Value="{DynamicResource ThemeBackgroundColor}" />

View File

@@ -7768,7 +7768,7 @@
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "颜色",
"zh_TW": ""
}
},
@@ -19018,7 +19018,7 @@
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "LED 设置",
"zh_TW": ""
}
},

View File

@@ -5,6 +5,7 @@ using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Logging.Targets;
@@ -26,6 +27,7 @@ using Ryujinx.SDL2.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
namespace Ryujinx.Headless
@@ -286,6 +288,9 @@ namespace Ryujinx.Headless
GraphicsConfig.EnableMacroHLE = !option.DisableMacroHLE;
DriverUtilities.InitDriverConfig(option.BackendThreading == BackendThreading.Off);
if (_inputConfiguration.OfType<StandardControllerInputConfig>().Any(ic => ic.Led.UseRainbow))
Rainbow.Enable();
while (true)
{

View File

@@ -206,6 +206,16 @@ namespace Ryujinx.Ava
_ => ConfigurationState.Instance.Graphics.GraphicsBackend
};
// Check if backend threading was overridden
if (CommandLineState.OverrideBackendThreading is not null)
ConfigurationState.Instance.Graphics.BackendThreading.Value = CommandLineState.OverrideBackendThreading.ToLower() switch
{
"auto" => BackendThreading.Auto,
"off" => BackendThreading.Off,
"on" => BackendThreading.On,
_ => ConfigurationState.Instance.Graphics.BackendThreading
};
// Check if docked mode was overriden.
if (CommandLineState.OverrideDockedMode.HasValue)
ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value;

View File

@@ -123,13 +123,11 @@
<Generator>MSBuild:Compile</Generator>
</AvaloniaResource>
<AvaloniaResource Include="Assets\Styles\Styles.xaml" />
<AvaloniaResource Include="Assets\Styles\CheckboxMenuItemStyle.axaml" />
</ItemGroup>
<ItemGroup>
<None Remove="Assets\locales.json" />
<None Remove="Assets\Styles\Themes.xaml" />
<None Remove="Assets\Styles\CheckboxMenuItemStyle.xaml" />
<None Remove="Assets\Icons\Controller_JoyConLeft.svg" />
<None Remove="Assets\Icons\Controller_JoyConPair.svg" />
<None Remove="Assets\Icons\Controller_JoyConRight.svg" />
@@ -151,7 +149,6 @@
</EmbeddedResource>
<EmbeddedResource Include="Assets\locales.json" />
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
<EmbeddedResource Include="Assets\Styles\CheckboxMenuItemStyle.axaml" />
<EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
<EmbeddedResource Include="Assets\Icons\Controller_JoyConPair.svg" />
<EmbeddedResource Include="Assets\Icons\Controller_JoyConRight.svg" />

View File

@@ -16,6 +16,5 @@
<Application.Styles>
<sty:FluentAvaloniaTheme PreferUserAccentColor="True" PreferSystemTheme="False" />
<StyleInclude Source="/Assets/Styles/Styles.xaml" />
<StyleInclude Source="/Assets/Styles/CheckboxMenuItemStyle.axaml"/>
</Application.Styles>
</Application>

View File

@@ -13,11 +13,6 @@
mc:Ignorable="d"
Focusable="True"
x:DataType="viewModels:UserSelectorDialogViewModel">
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources>
<Design.DataContext>
<viewModels:UserSelectorDialogViewModel />
</Design.DataContext>
@@ -80,7 +75,7 @@
Height="96"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
Source="{Binding Image, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
<TextBlock
HorizontalAlignment="Stretch"
MaxWidth="90"
@@ -110,12 +105,5 @@
</ListBox>
</Border>
<StackPanel
Grid.Row="1"
Margin="0 24 0 0"
HorizontalAlignment="Left"
Orientation="Horizontal"
Spacing="10">
</StackPanel>
</Grid>
</UserControl>

View File

@@ -128,7 +128,11 @@ namespace Ryujinx.Ava.UI.Controls
public async void OpenModManager_Click(object sender, RoutedEventArgs args)
{
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
await ModManagerWindow.Show(viewModel.SelectedApplication.Id, viewModel.SelectedApplication.Name);
await ModManagerWindow.Show(
viewModel.SelectedApplication.Id,
viewModel.SelectedApplication.IdBase,
viewModel.ApplicationLibrary,
viewModel.SelectedApplication.Name);
}
public async void PurgePtcCache_Click(object sender, RoutedEventArgs args)

View File

@@ -13,9 +13,6 @@
mc:Ignorable="d"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
x:DataType="viewModels:MainWindowViewModel">
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
@@ -68,7 +65,7 @@
Grid.Row="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
Source="{Binding Icon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
<Panel
Grid.Row="1"
Height="50"

View File

@@ -12,9 +12,6 @@
mc:Ignorable="d"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
x:DataType="viewModels:MainWindowViewModel">
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
@@ -62,7 +59,7 @@
Classes.large="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridLarge}"
Classes.normal="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridMedium}"
Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
Source="{Binding Icon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
<Border
Grid.Column="2"
Margin="0,0,5,0"

View File

@@ -9,7 +9,7 @@ namespace Ryujinx.Ava.UI.Helpers
{
internal class BitmapArrayValueConverter : IValueConverter
{
public static BitmapArrayValueConverter Instance = new();
public static readonly BitmapArrayValueConverter Instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Ava.UI.Helpers
{
internal class DownloadableContentLabelConverter : IMultiValueConverter
{
public static DownloadableContentLabelConverter Instance = new();
public static readonly DownloadableContentLabelConverter Instance = new();
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
{

View File

@@ -10,7 +10,7 @@ namespace Ryujinx.Ava.UI.Helpers
{
internal class KeyValueConverter : IValueConverter
{
public static KeyValueConverter Instance = new();
public static readonly KeyValueConverter Instance = new();
private static readonly Dictionary<Key, LocaleKeys> _keysMap = new()
{

View File

@@ -1,6 +1,5 @@
using Avalonia.Data.Converters;
using Avalonia.Markup.Xaml;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Utilities.AppLibrary;
using System;
using System.Globalization;
@@ -19,15 +18,10 @@ namespace Ryujinx.Ava.UI.Helpers
{
return $"Hosted Games: {applicationData.GameCount}\nOnline Players: {applicationData.PlayerCount}";
}
else
{
return "";
}
}
else
{
return "";
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Ava.UI.Helpers
{
internal class TitleUpdateLabelConverter : IMultiValueConverter
{
public static TitleUpdateLabelConverter Instance = new();
public static readonly TitleUpdateLabelConverter Instance = new();
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
{

View File

@@ -12,7 +12,7 @@ namespace Ryujinx.Ava.UI.Helpers
internal class XCITrimmerFileSpaceSavingsConverter : IValueConverter
{
private const long _bytesPerMB = 1024 * 1024;
public static XCITrimmerFileSpaceSavingsConverter Instance = new();
public static readonly XCITrimmerFileSpaceSavingsConverter Instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{

View File

@@ -9,7 +9,7 @@ namespace Ryujinx.Ava.UI.Models
{
private bool _isEnabled = false;
public ObservableCollection<CheatNode> SubNodes { get; } = [];
public string CleanName => Name[1..^7];
public string CleanName => Name.Length > 0 ? Name[1..^7] : Name;
public string BuildIdKey => $"{BuildId}-{Name}";
public bool IsRootNode { get; }
public string Name { get; }

View File

@@ -5,6 +5,7 @@ using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.Common.Utilities;
using Ryujinx.UI.Views.Input;
namespace Ryujinx.Ava.UI.ViewModels.Input
@@ -48,6 +49,23 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
ParentModel = model;
model.NotifyChangesEvent += OnParentModelChanged;
OnParentModelChanged();
config.PropertyChanged += (_, args) =>
{
if (args.PropertyName is nameof(Config.UseRainbowLed))
{
if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true })
Rainbow.Updated += color => ParentModel.SelectedGamepad.SetLed((uint)color);
else
{
Rainbow.Reset();
if (Config.TurnOffLed)
ParentModel.SelectedGamepad.ClearLed();
else
ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32());
}
}
};
Config = config;
}

View File

@@ -20,6 +20,7 @@ using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
using Ryujinx.Input;
using Ryujinx.Input.SDL2;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -63,7 +64,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
get => _selectedGamepad;
private set
{
Rainbow.Reset();
_selectedGamepad = value;
if (ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true })
Rainbow.Updated += color => _selectedGamepad.SetLed((uint)color);
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
}
}

View File

@@ -7,6 +7,7 @@ using Gommon;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
@@ -29,6 +30,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private string _search;
private readonly ulong _applicationId;
private readonly ulong[] _installedDlcIds;
private readonly IStorageProvider _storageProvider;
private static readonly ModMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
@@ -61,18 +63,23 @@ namespace Ryujinx.Ava.UI.ViewModels
get => string.Format(LocaleManager.Instance[LocaleKeys.ModWindowHeading], Mods.Count);
}
public ModManagerViewModel(ulong applicationId)
public ModManagerViewModel(ulong applicationId, ulong applicationIdBase, ApplicationLibrary appLibrary)
{
_applicationId = applicationId;
_installedDlcIds = appLibrary.DownloadableContents.Keys
.Where(x => x.TitleIdBase == applicationIdBase)
.Select(x => x.TitleId)
.ToArray();
_modJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationId.ToString("x16"), "mods.json");
_storageProvider = RyujinxApp.MainWindow.StorageProvider;
LoadMods(applicationId);
LoadMods(applicationId, _installedDlcIds);
}
private void LoadMods(ulong applicationId)
private void LoadMods(ulong applicationId, ulong[] installedDlcIds)
{
Mods.Clear();
SelectedMods.Clear();
@@ -84,7 +91,7 @@ namespace Ryujinx.Ava.UI.ViewModels
bool inSd = path == ModLoader.GetSdModsBasePath();
ModLoader.ModCache modCache = new();
ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId);
ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId, _installedDlcIds);
foreach (ModLoader.Mod<DirectoryInfo> mod in modCache.RomfsDirs)
{
@@ -278,7 +285,7 @@ namespace Ryujinx.Ava.UI.ViewModels
File.Copy(file, file.Replace(directory.Parent.ToString(), destinationDir), true);
}
LoadMods(_applicationId);
LoadMods(_applicationId, _installedDlcIds);
}
public async void Add()

View File

@@ -20,9 +20,6 @@
<Design.DataContext>
<viewModels:ControllerInputViewModel />
</Design.DataContext>
<UserControl.Resources>
<helpers:KeyValueConverter x:Key="Key" />
</UserControl.Resources>
<UserControl.Styles>
<Style Selector="ToggleButton">
<Setter Property="Width" Value="90" />
@@ -78,7 +75,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonZl">
<TextBlock
Text="{Binding Config.ButtonZl, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonZl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -94,7 +91,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonL">
<TextBlock
Text="{Binding Config.ButtonL, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonL, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -110,7 +107,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonMinus">
<TextBlock
Text="{Binding Config.ButtonMinus, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonMinus, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -144,7 +141,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftStickButton">
<TextBlock
Text="{Binding Config.LeftStickButton, Converter={StaticResource Key}}"
Text="{Binding Config.LeftStickButton, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -161,7 +158,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftJoystick" Tag="stick">
<TextBlock
Text="{Binding Config.LeftJoystick, Converter={StaticResource Key}}"
Text="{Binding Config.LeftJoystick, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -254,7 +251,7 @@
TextAlignment="Center" />
<ToggleButton Name="DpadUp">
<TextBlock
Text="{Binding Config.DpadUp, Converter={StaticResource Key}}"
Text="{Binding Config.DpadUp, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -271,7 +268,7 @@
TextAlignment="Center" />
<ToggleButton Name="DpadDown">
<TextBlock
Text="{Binding Config.DpadDown, Converter={StaticResource Key}}"
Text="{Binding Config.DpadDown, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -288,7 +285,7 @@
TextAlignment="Center" />
<ToggleButton Name="DpadLeft">
<TextBlock
Text="{Binding Config.DpadLeft, Converter={StaticResource Key}}"
Text="{Binding Config.DpadLeft, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -305,7 +302,7 @@
TextAlignment="Center" />
<ToggleButton Name="DpadRight">
<TextBlock
Text="{Binding Config.DpadRight, Converter={StaticResource Key}}"
Text="{Binding Config.DpadRight, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -368,7 +365,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftButtonSr">
<TextBlock
Text="{Binding Config.LeftButtonSr, Converter={StaticResource Key}}"
Text="{Binding Config.LeftButtonSr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -386,7 +383,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftButtonSl">
<TextBlock
Text="{Binding Config.LeftButtonSl, Converter={StaticResource Key}}"
Text="{Binding Config.LeftButtonSl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -404,7 +401,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightButtonSr">
<TextBlock
Text="{Binding Config.RightButtonSr, Converter={StaticResource Key}}"
Text="{Binding Config.RightButtonSr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -422,7 +419,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightButtonSl">
<TextBlock
Text="{Binding Config.RightButtonSl, Converter={StaticResource Key}}"
Text="{Binding Config.RightButtonSl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -550,7 +547,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonZr">
<TextBlock
Text="{Binding Config.ButtonZr, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonZr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -568,7 +565,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonR">
<TextBlock
Text="{Binding Config.ButtonR, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonR, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -586,7 +583,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonPlus">
<TextBlock
Text="{Binding Config.ButtonPlus, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonPlus, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -621,7 +618,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonA">
<TextBlock
Text="{Binding Config.ButtonA, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonA, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -638,7 +635,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonB">
<TextBlock
Text="{Binding Config.ButtonB, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonB, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -655,7 +652,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonX">
<TextBlock
Text="{Binding Config.ButtonX, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonX, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -672,7 +669,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonY">
<TextBlock
Text="{Binding Config.ButtonY, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonY, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -706,7 +703,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightStickButton">
<TextBlock
Text="{Binding Config.RightStickButton, Converter={StaticResource Key}}"
Text="{Binding Config.RightStickButton, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -724,7 +721,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightJoystick" Tag="stick">
<TextBlock
Text="{Binding Config.RightJoystick, Converter={StaticResource Key}}"
Text="{Binding Config.RightJoystick, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>

View File

@@ -18,9 +18,6 @@
<Design.DataContext>
<viewModels:KeyboardInputViewModel />
</Design.DataContext>
<UserControl.Resources>
<helpers:KeyValueConverter x:Key="Key" />
</UserControl.Resources>
<UserControl.Styles>
<Style Selector="ToggleButton">
<Setter Property="Width" Value="90" />
@@ -76,7 +73,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonZl">
<TextBlock
Text="{Binding Config.ButtonZl, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonZl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -92,7 +89,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonL">
<TextBlock
Text="{Binding Config.ButtonL, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonL, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -108,7 +105,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonMinus">
<TextBlock
Text="{Binding Config.ButtonMinus, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonMinus, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -143,7 +140,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftStickButton">
<TextBlock
Text="{Binding Config.LeftStickButton, Converter={StaticResource Key}}"
Text="{Binding Config.LeftStickButton, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -160,7 +157,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftStickUp">
<TextBlock
Text="{Binding Config.LeftStickUp, Converter={StaticResource Key}}"
Text="{Binding Config.LeftStickUp, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -177,7 +174,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftStickDown">
<TextBlock
Text="{Binding Config.LeftStickDown, Converter={StaticResource Key}}"
Text="{Binding Config.LeftStickDown, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -194,7 +191,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftStickLeft">
<TextBlock
Text="{Binding Config.LeftStickLeft, Converter={StaticResource Key}}"
Text="{Binding Config.LeftStickLeft, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -211,7 +208,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftStickRight">
<TextBlock
Text="{Binding Config.LeftStickRight, Converter={StaticResource Key}}"
Text="{Binding Config.LeftStickRight, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -247,7 +244,7 @@
TextAlignment="Center" />
<ToggleButton Name="DpadUp">
<TextBlock
Text="{Binding Config.DpadUp, Converter={StaticResource Key}}"
Text="{Binding Config.DpadUp, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -264,7 +261,7 @@
TextAlignment="Center" />
<ToggleButton Name="DpadDown">
<TextBlock
Text="{Binding Config.DpadDown, Converter={StaticResource Key}}"
Text="{Binding Config.DpadDown, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -281,7 +278,7 @@
TextAlignment="Center" />
<ToggleButton Name="DpadLeft">
<TextBlock
Text="{Binding Config.DpadLeft, Converter={StaticResource Key}}"
Text="{Binding Config.DpadLeft, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -298,7 +295,7 @@
TextAlignment="Center" />
<ToggleButton Name="DpadRight">
<TextBlock
Text="{Binding Config.DpadRight, Converter={StaticResource Key}}"
Text="{Binding Config.DpadRight, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -341,7 +338,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftButtonSr">
<TextBlock
Text="{Binding Config.LeftButtonSr, Converter={StaticResource Key}}"
Text="{Binding Config.LeftButtonSr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -359,7 +356,7 @@
TextAlignment="Center" />
<ToggleButton Name="LeftButtonSl">
<TextBlock
Text="{Binding Config.LeftButtonSl, Converter={StaticResource Key}}"
Text="{Binding Config.LeftButtonSl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -377,7 +374,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightButtonSr">
<TextBlock
Text="{Binding Config.RightButtonSr, Converter={StaticResource Key}}"
Text="{Binding Config.RightButtonSr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -395,7 +392,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightButtonSl">
<TextBlock
Text="{Binding Config.RightButtonSl, Converter={StaticResource Key}}"
Text="{Binding Config.RightButtonSl, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -437,7 +434,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonZr">
<TextBlock
Text="{Binding Config.ButtonZr, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonZr, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -455,7 +452,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonR">
<TextBlock
Text="{Binding Config.ButtonR, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonR, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -473,7 +470,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonPlus">
<TextBlock
Text="{Binding Config.ButtonPlus, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonPlus, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -508,7 +505,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonA">
<TextBlock
Text="{Binding Config.ButtonA, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonA, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -525,7 +522,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonB">
<TextBlock
Text="{Binding Config.ButtonB, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonB, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -542,7 +539,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonX">
<TextBlock
Text="{Binding Config.ButtonX, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonX, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -559,7 +556,7 @@
TextAlignment="Center" />
<ToggleButton Name="ButtonY">
<TextBlock
Text="{Binding Config.ButtonY, Converter={StaticResource Key}}"
Text="{Binding Config.ButtonY, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -594,7 +591,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightStickButton">
<TextBlock
Text="{Binding Config.RightStickButton, Converter={StaticResource Key}}"
Text="{Binding Config.RightStickButton, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -611,7 +608,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightStickUp">
<TextBlock
Text="{Binding Config.RightStickUp, Converter={StaticResource Key}}"
Text="{Binding Config.RightStickUp, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -628,7 +625,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightStickDown">
<TextBlock
Text="{Binding Config.RightStickDown, Converter={StaticResource Key}}"
Text="{Binding Config.RightStickDown, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -645,7 +642,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightStickLeft">
<TextBlock
Text="{Binding Config.RightStickLeft, Converter={StaticResource Key}}"
Text="{Binding Config.RightStickLeft, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
@@ -662,7 +659,7 @@
TextAlignment="Center" />
<ToggleButton Name="RightStickRight">
<TextBlock
Text="{Binding Config.RightStickRight, Converter={StaticResource Key}}"
Text="{Binding Config.RightStickRight, Converter={x:Static helpers:KeyValueConverter.Instance}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>

View File

@@ -134,7 +134,12 @@ namespace Ryujinx.Ava.UI.Views.Main
{
Window.SettingsWindow = new(Window.VirtualFileSystem, Window.ContentManager);
Rainbow.Enable();
await Window.SettingsWindow.ShowDialog(Window);
Rainbow.Disable();
Rainbow.Reset();
Window.SettingsWindow = null;

View File

@@ -14,9 +14,6 @@
<Design.DataContext>
<viewModels:SettingsViewModel />
</Design.DataContext>
<UserControl.Resources>
<helpers:KeyValueConverter x:Key="Key" />
</UserControl.Resources>
<UserControl.Styles>
<Style Selector="StackPanel > StackPanel">
<Setter Property="Margin" Value="10, 0, 0, 0" />
@@ -52,67 +49,67 @@
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" />
<ToggleButton Name="ToggleVSyncMode">
<TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysScreenshotHotkey}" />
<ToggleButton Name="Screenshot">
<TextBlock Text="{Binding KeyboardHotkey.Screenshot, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.Screenshot, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysShowUiHotkey}" />
<ToggleButton Name="ShowUI">
<TextBlock Text="{Binding KeyboardHotkey.ShowUI, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.ShowUI, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysPauseHotkey}" />
<ToggleButton Name="Pause">
<TextBlock Text="{Binding KeyboardHotkey.Pause, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.Pause, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleMuteHotkey}" />
<ToggleButton Name="ToggleMute">
<TextBlock Text="{Binding KeyboardHotkey.ToggleMute, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.ToggleMute, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleUpHotkey}" />
<ToggleButton Name="ResScaleUp">
<TextBlock Text="{Binding KeyboardHotkey.ResScaleUp, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.ResScaleUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleDownHotkey}" />
<ToggleButton Name="ResScaleDown">
<TextBlock Text="{Binding KeyboardHotkey.ResScaleDown, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.ResScaleDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeUpHotkey}" />
<ToggleButton Name="VolumeUp">
<TextBlock Text="{Binding KeyboardHotkey.VolumeUp, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.VolumeUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeDownHotkey}" />
<ToggleButton Name="VolumeDown">
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" />
<ToggleButton Name="CustomVSyncIntervalIncrement">
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" />
<ToggleButton Name="CustomVSyncIntervalDecrement">
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={StaticResource Key}}" />
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
</StackPanel>
</StackPanel>

View File

@@ -7,23 +7,26 @@ namespace Ryujinx.Ava.UI.Views.Settings
{
public partial class SettingsNetworkView : UserControl
{
private readonly Random _random;
public SettingsViewModel ViewModel;
public SettingsNetworkView()
{
_random = new Random();
InitializeComponent();
}
private void GenLdnPassButton_OnClick(object sender, RoutedEventArgs e)
{
byte[] code = new byte[4];
new Random().NextBytes(code);
_random.NextBytes(code);
ViewModel.LdnPassphrase = $"Ryujinx-{BitConverter.ToUInt32(code):x8}";
}
private void ClearLdnPassButton_OnClick(object sender, RoutedEventArgs e)
{
ViewModel.LdnPassphrase = "";
ViewModel.LdnPassphrase = string.Empty;
}
}
}

View File

@@ -10,9 +10,6 @@
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
mc:Ignorable="d"
x:DataType="viewModels:SettingsViewModel">
<UserControl.Resources>
<helpers:TimeZoneConverter x:Key="TimeZone" />
</UserControl.Resources>
<Design.DataContext>
<viewModels:SettingsViewModel />
</Design.DataContext>
@@ -162,7 +159,7 @@
Text="{Binding Path=TimeZone, Mode=OneWay}"
TextChanged="TimeZoneBox_OnTextChanged"
ToolTip.Tip="{ext:Locale TimezoneTooltip}"
ValueMemberBinding="{Binding Mode=OneWay, Converter={StaticResource TimeZone}}" />
ValueMemberBinding="{Binding Mode=OneWay, Converter={x:Static helpers:TimeZoneConverter.Instance}}" />
</StackPanel>
<StackPanel
Margin="0,0,0,10"

View File

@@ -14,9 +14,6 @@
mc:Ignorable="d"
Focusable="True"
x:DataType="models:TempProfile">
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources>
<Grid Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -74,7 +71,7 @@
Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
Source="{Binding Image, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
</Panel>
</Border>
</StackPanel>

View File

@@ -17,9 +17,6 @@
<Design.DataContext>
<viewModels:UserFirmwareAvatarSelectorViewModel />
</Design.DataContext>
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources>
<Grid
Margin="0"
HorizontalAlignment="Stretch"
@@ -62,7 +59,7 @@
<Panel
Background="{Binding BackgroundColor}"
Margin="5">
<Image Source="{Binding Data, Converter={StaticResource ByteImage}}" />
<Image Source="{Binding Data, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
</Panel>
</DataTemplate>
</ListBox.ItemTemplate>

View File

@@ -19,9 +19,6 @@
<Design.DataContext>
<viewModels:UserSaveManagerViewModel />
</Design.DataContext>
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@@ -147,7 +144,7 @@
IsVisible="{Binding InGameList}"
Width="42"
Height="42"
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
Source="{Binding Icon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
<TextBlock
MaxLines="3"
Width="320"

View File

@@ -15,9 +15,6 @@
mc:Ignorable="d"
Focusable="True"
x:DataType="viewModels:UserProfileViewModel">
<UserControl.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources>
<Design.DataContext>
<viewModels:UserProfileViewModel />
</Design.DataContext>
@@ -74,7 +71,7 @@
Height="96"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
Source="{Binding Image, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
<TextBlock
HorizontalAlignment="Stretch"
MaxWidth="90"

View File

@@ -6,8 +6,8 @@
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
Width="500"
Height="500"
Width="600"
Height="750"
MinWidth="500"
MinHeight="500"
x:DataType="window:CheatWindow"

View File

@@ -34,6 +34,9 @@ namespace Ryujinx.Ava.UI.Windows
public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath)
{
MinWidth = 500;
MinHeight = 650;
LoadedCheats = [];
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
@@ -61,7 +64,7 @@ namespace Ryujinx.Ava.UI.Windows
ModLoader.ModCache mods = new();
ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue);
ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue, []);
string currentCheatFile = string.Empty;
string buildId = string.Empty;

View File

@@ -30,9 +30,6 @@
<Design.DataContext>
<viewModels:MainWindowViewModel />
</Design.DataContext>
<Window.Resources>
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
</Window.Resources>
<Window.KeyBindings>
<KeyBinding Gesture="Alt+Return" Command="{Binding ToggleFullscreen}" />
<KeyBinding Gesture="F11" Command="{Binding ToggleFullscreen}" />
@@ -121,7 +118,7 @@
Width="256"
Height="256"
IsVisible="{Binding ShowLoadProgress}"
Source="{Binding SelectedIcon, Converter={StaticResource ByteImage}}" />
Source="{Binding SelectedIcon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
</Border>
<Grid
Grid.Column="1"

View File

@@ -6,6 +6,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Helper;
using System.Threading.Tasks;
using Button = Avalonia.Controls.Button;
@@ -23,21 +24,21 @@ namespace Ryujinx.Ava.UI.Windows
InitializeComponent();
}
public ModManagerWindow(ulong titleId)
public ModManagerWindow(ulong titleId, ulong titleIdBase, ApplicationLibrary applicationLibrary)
{
DataContext = ViewModel = new ModManagerViewModel(titleId);
DataContext = ViewModel = new ModManagerViewModel(titleId, titleIdBase, applicationLibrary);
InitializeComponent();
}
public static async Task Show(ulong titleId, string titleName)
public static async Task Show(ulong titleId, ulong titleIdBase, ApplicationLibrary appLibrary, string titleName)
{
ContentDialog contentDialog = new()
{
PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty,
CloseButtonText = string.Empty,
Content = new ModManagerWindow(titleId),
Content = new ModManagerWindow(titleId, titleIdBase, appLibrary),
Title = string.Format(LocaleManager.Instance[LocaleKeys.ModWindowTitle], titleName, titleId.ToString("X16")),
};

View File

@@ -14,9 +14,6 @@
mc:Ignorable="d"
x:DataType="viewModels:TitleUpdateViewModel"
Focusable="True">
<UserControl.Resources>
<helpers:TitleUpdateLabelConverter x:Key="TitleUpdateLabel" />
</UserControl.Resources>
<Grid RowDefinitions="Auto,*,Auto">
<StackPanel
Grid.Row="0"
@@ -57,7 +54,7 @@
VerticalAlignment="Center"
TextWrapping="Wrap">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource TitleUpdateLabel}">
<MultiBinding Converter="{x:Static helpers:TitleUpdateLabelConverter.Instance}">
<Binding Path="DisplayVersion" />
<Binding Path="IsBundled" />
</MultiBinding>

View File

@@ -13,11 +13,6 @@
x:DataType="viewModels:XCITrimmerViewModel"
Focusable="True"
mc:Ignorable="d">
<UserControl.Resources>
<helpers:XCITrimmerFileStatusConverter x:Key="StatusLabel" />
<helpers:XCITrimmerFileStatusDetailConverter x:Key="StatusDetailLabel" />
<helpers:XCITrimmerFileSpaceSavingsConverter x:Key="SpaceSavingsLabel" />
</UserControl.Resources>
<Grid Margin="20 0 20 0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@@ -186,7 +181,7 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
MaxLines="1"
Text="{Binding ., Converter={StaticResource StatusLabel}}">
Text="{Binding ., Converter={x:Static helpers:XCITrimmerFileStatusConverter.Instance}}">
<ToolTip.Tip>
<StackPanel
IsVisible="{Binding IsFailed}">
@@ -194,7 +189,7 @@
Classes="h1"
Text="{ext:Locale XCITrimmerTitleStatusFailed}" />
<TextBlock
Text="{Binding ., Converter={StaticResource StatusDetailLabel}}"
Text="{Binding ., Converter={x:Static helpers:XCITrimmerFileStatusDetailConverter.Instance}}"
MaxLines="5"
MaxWidth="200"
MaxHeight="100"
@@ -209,7 +204,7 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
MaxLines="1"
Text="{Binding ., Converter={StaticResource SpaceSavingsLabel}}">>
Text="{Binding ., Converter={x:Static helpers:XCITrimmerFileSpaceSavingsConverter.Instance}}">>
</TextBlock>
</Grid>
</Grid>

View File

@@ -10,6 +10,7 @@ namespace Ryujinx.Ava.Utilities
public static bool? OverrideDockedMode { get; private set; }
public static bool? OverrideHardwareAcceleration { get; private set; }
public static string OverrideGraphicsBackend { get; private set; }
public static string OverrideBackendThreading { get; private set; }
public static string OverrideHideCursor { get; private set; }
public static string BaseDirPathArg { get; private set; }
public static string Profile { get; private set; }
@@ -74,6 +75,16 @@ namespace Ryujinx.Ava.Utilities
OverrideGraphicsBackend = args[++i];
break;
case "--backend-threading":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
OverrideBackendThreading = args[++i];
break;
case "-i":
case "--application-id":
LaunchApplicationId = args[++i];

View File

@@ -204,8 +204,8 @@ namespace Ryujinx.Ava.Utilities.Configuration
Multiplayer.LanInterfaceId.Value = "0";
Multiplayer.Mode.Value = MultiplayerMode.Disabled;
Multiplayer.DisableP2p.Value = false;
Multiplayer.LdnPassphrase.Value = "";
Multiplayer.LdnServer.Value = "";
Multiplayer.LdnPassphrase.Value = string.Empty;
Multiplayer.LdnServer.Value = string.Empty;
UI.GuiColumns.FavColumn.Value = true;
UI.GuiColumns.IconColumn.Value = true;
UI.GuiColumns.AppColumn.Value = true;