Compare commits

..

46 Commits

Author SHA1 Message Date
Evan Husted af44726cec Merge branch 'master' into validation-v2 2024-12-28 05:51:19 -06:00
LotP1 8efefeaaca slight refactor
isGitRunner is now a variable passed to all tasks.
Validation project can now accept more arguments, only the first argument is used at the moment.
Execute is no longer static, and you can now pass extra data to the task constructor if needed.
2024-12-28 02:16:17 +01:00
LotP1 4e56b1493f validate that line endings are LF on build
if running on git it will now fail if the file contains CRLF line endings and tell the user to run a local build to fix it.
2024-12-28 02:01:23 +01:00
LotP1 43f6e4a873 remove dupelicates 2024-12-28 01:58:35 +01:00
LotP1 55f6b95d8d Merge remote-tracking branch 'upstream/master' into validation-v2 2024-12-28 01:50:18 +01:00
LotP1 4b84c5d240 fix duplicates 2024-12-28 01:39:03 +01:00
LotP1 9f22fc49c8 Merge branch 'master' into validation-v2 2024-12-28 01:38:32 +01:00
LotP1 4f206d0e73 Merge remote-tracking branch 'upstream/master' into validation-v2 2024-12-28 01:35:52 +01:00
LotP1 e2e8502278 force line endings to use LF 2024-12-27 12:10:50 +01:00
Evan Husted aa806b1032 Rename program.cs to Program.cs 2024-12-26 21:07:29 -06:00
LotP1 aabb786016 fix spelling and names 2024-12-26 23:42:53 +01:00
LotP1 2a38f1bbbf only log runtime if a runtime is set 2024-12-26 23:34:43 +01:00
LotP1 fdece62f88 fix matching windows runner 2024-12-26 23:32:14 +01:00
LotP1 6fb58a611e revert .gitignore 2024-12-26 23:28:34 +01:00
LotP1 02ff76f89a revert packages.props 2024-12-26 23:26:50 +01:00
LotP1 d39b3a5864 fix locales.json to comply with validation 2024-12-26 23:20:29 +01:00
LotP1 f976c3c362 simplify 2024-12-26 23:20:06 +01:00
LotP1 d9f2b813a0 Merge remote-tracking branch 'upstream/master' into validation-v2 2024-12-26 23:12:30 +01:00
LotP1 8cb6767c7c slash instead of backslash 2024-12-26 23:10:36 +01:00
LotP1 80377c1553 run with dotnet dll runner 2024-12-26 23:04:05 +01:00
LotP1 1dbcaf1fd7 missing quote, will still fail 2024-12-26 22:57:07 +01:00
LotP1 bad1f72918 v4 first test, will fail due to new validation step 2024-12-26 22:54:22 +01:00
LotP1 a317184594 check target dir 2024-12-26 21:34:07 +01:00
LotP1 0cde245875 forgot to remove true 2024-12-26 21:31:24 +01:00
LotP1 e3638d13b1 correct form of --runtime 2024-12-26 21:29:10 +01:00
LotP1 2fe19044cf use RuntimeIdentifier instead 2024-12-26 21:25:45 +01:00
LotP1 9320decc45 test RuntimeIdentifiers 2024-12-26 21:06:08 +01:00
LotP1 35b23bcafb try simplified csproj and force runtime identifier 2024-12-26 20:45:37 +01:00
LotP1 4add4829c7 force restore 2024-12-26 20:38:46 +01:00
LotP1 eb46909808 manually run dotnet restore 2024-12-26 20:29:56 +01:00
LotP1 c91d9d8049 build target fix 2024-12-26 20:18:29 +01:00
LotP1 21f23f0a2e lets see what's actually going on 2024-12-26 20:13:18 +01:00
LotP1 9ca0926439 confirm that it actually builds 2024-12-26 20:07:45 +01:00
LotP1 7b8c8776a2 Revert "use outdir"
This reverts commit b00d80c17a.
2024-12-26 20:06:07 +01:00
LotP1 b00d80c17a use outdir 2024-12-26 20:00:04 +01:00
LotP1 8c0a82bb6e v4 2024-12-26 19:54:02 +01:00
LotP1 1bac6ab19e please 2024-12-26 00:00:05 +01:00
LotP1 dac137fd43 test stuff 2024-12-25 23:47:20 +01:00
LotP1 d83d80de73 here we go 2024-12-25 23:22:38 +01:00
LotP1 097836bfac NO-BREAK SPACE is now escaped 2024-12-25 22:14:20 +01:00
LotP1 695f9e277d v3 2024-12-25 22:13:54 +01:00
LotP1 b19ee23c6b this won't work 2024-12-25 20:48:28 +01:00
LotP1 748e93ba65 lets give this another shot
moved from netstandard to netframework
2024-12-25 17:09:57 +01:00
LotP1 732a1af863 copying is not necessary anymore 2024-12-25 04:02:22 +01:00
LotP1 f538cee2e8 please don't fail 2024-12-25 03:56:59 +01:00
LotP1 4275a778aa update gitignore 2024-12-24 23:28:44 +01:00
171 changed files with 2215 additions and 1449 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ jobs:
if (!artifacts.length) { if (!artifacts.length) {
return core.error(`No artifacts found`); return core.error(`No artifacts found`);
} }
let body = `*You need to be logged into GitHub to download these files.*\n\nDownload the artifacts for this pull request:\n`; let body = `Download the artifacts for this pull request:\n`;
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`; let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
for (const art of artifacts) { for (const art of artifacts) {
const url = `https://github.com/Ryubing/Ryujinx/actions/runs/${run_id}/artifacts/${art.id}`; const url = `https://github.com/Ryubing/Ryujinx/actions/runs/${run_id}/artifacts/${art.id}`;
+1 -2
View File
@@ -17,7 +17,6 @@
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/> <PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/> <PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
<PackageVersion Include="CommandLineParser" Version="2.9.1" /> <PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
<PackageVersion Include="Concentus" Version="2.2.0" /> <PackageVersion Include="Concentus" Version="2.2.0" />
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" /> <PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageVersion Include="DynamicData" Version="9.0.4" /> <PackageVersion Include="DynamicData" Version="9.0.4" />
@@ -42,7 +41,7 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" /> <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.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
<PackageVersion Include="Gommon" Version="2.7.0.1" /> <PackageVersion Include="Gommon" Version="2.6.8" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" /> <PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpMetal" Version="1.0.0-preview21" /> <PackageVersion Include="SharpMetal" Version="1.0.0-preview21" />
+6
View File
@@ -61,6 +61,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmp
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
@@ -217,6 +219,10 @@ Global
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU {7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU {7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU {7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.Build.0 = Release|Any CPU
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU {6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU {6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -13,7 +13,7 @@ mkdir -p AppDir/usr/bin
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
cp distribution/linux/appimage/AppRun AppDir/AppRun cp distribution/linux/appimage/AppRun AppDir/AppRun
cp distribution/misc/Logo.svg AppDir/Ryujinx.svg cp src/Ryujinx.UI.Common/Resources/Logo_Ryujinx.png AppDir/Ryujinx.svg
cp -r "$BUILDDIR"/* AppDir/usr/bin/ cp -r "$BUILDDIR"/* AppDir/usr/bin/
@@ -9,12 +9,20 @@ namespace Ryujinx.Audio.Backends.Dummy
{ {
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
{ {
private readonly ManualResetEvent _updateRequiredEvent = new(false); private readonly ManualResetEvent _updateRequiredEvent;
private readonly ManualResetEvent _pauseEvent = new(true); private readonly ManualResetEvent _pauseEvent;
public static bool IsSupported => true; public static bool IsSupported => true;
public float Volume { get; set; } = 1f; public float Volume { get; set; }
public DummyHardwareDeviceDriver()
{
_updateRequiredEvent = new ManualResetEvent(false);
_pauseEvent = new ManualResetEvent(true);
Volume = 1f;
}
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount) public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
{ {
@@ -52,7 +60,7 @@ namespace Ryujinx.Audio.Backends.Dummy
Dispose(true); Dispose(true);
} }
private void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {
@@ -1,7 +0,0 @@
namespace Ryujinx.BuildValidationTasks
{
public interface IValidationTask
{
public bool Execute(string projectPath, bool isGitRunner);
}
}
@@ -7,7 +7,7 @@ using System.Text.Encodings.Web;
namespace Ryujinx.BuildValidationTasks namespace Ryujinx.BuildValidationTasks
{ {
public class LocalesValidationTask : IValidationTask public class LocalesValidationTask : ValidationTask
{ {
public LocalesValidationTask() { } public LocalesValidationTask() { }
@@ -1,6 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ryujinx.BuildValidationTasks namespace Ryujinx.BuildValidationTasks
{ {
@@ -10,7 +10,6 @@
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\" <Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
Command="dotnet Ryujinx.BuildValidationTasks.dll &quot;$(ProjectDir)..\..\\&quot;" Command="dotnet Ryujinx.BuildValidationTasks.dll &quot;$(ProjectDir)..\..\\&quot;"
ConsoleToMsBuild="true" ConsoleToMsBuild="true"
Condition="'$(RuntimeIdentifier)' == ''"
/> />
</Target> </Target>
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ryujinx.BuildValidationTasks
{
public interface ValidationTask
{
public bool Execute(string projectPath, bool isGitRunner);
}
}
@@ -1,60 +0,0 @@
using Gommon;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Ryujinx.Common.Configuration
{
[Flags]
public enum DirtyHack : byte
{
Xc2MenuSoftlockFix = 1,
ShaderTranslationDelay = 2
}
public readonly struct EnabledDirtyHack(DirtyHack hack, int value)
{
public DirtyHack Hack => hack;
public int Value => value;
public ulong Pack() => Raw.PackBitFields(PackedFormat);
public static EnabledDirtyHack Unpack(ulong packedHack)
{
var unpackedFields = packedHack.UnpackBitFields(PackedFormat);
if (unpackedFields is not [var hack, var value])
throw new ArgumentException(nameof(packedHack));
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 DirtyHacks : Dictionary<DirtyHack, int>
{
public DirtyHacks(IEnumerable<EnabledDirtyHack> hacks)
=> hacks.ForEach(edh => Add(edh.Hack, edh.Value));
public DirtyHacks(ulong[] packedHacks) : this(packedHacks.Select(EnabledDirtyHack.Unpack)) {}
public ulong[] PackEntries()
=> Entries.Select(it => it.Pack()).ToArray();
public EnabledDirtyHack[] Entries
=> this
.Select(it => new EnabledDirtyHack(it.Key, it.Value))
.ToArray();
public static implicit operator DirtyHacks(EnabledDirtyHack[] hacks) => new(hacks);
public static implicit operator DirtyHacks(ulong[] packedHacks) => new(packedHacks);
public new int this[DirtyHack hack] => TryGetValue(hack, out var value) ? value : -1;
public bool IsEnabled(DirtyHack hack) => ContainsKey(hack);
}
}
@@ -8,10 +8,10 @@ namespace Ryujinx.Common
public static class StreamExtensions public static class StreamExtensions
{ {
/// <summary> /// <summary>
/// Writes an int span to this stream. /// Writes a <see cref="ReadOnlySpan{int}" /> to this stream.
/// ///
/// This default implementation converts each buffer value to a stack-allocated /// This default implementation converts each buffer value to a stack-allocated
/// byte array, then writes it to the Stream using <see cref="Stream.Write(ReadOnlySpan{byte})" />. /// byte array, then writes it to the Stream using <cref="System.Stream.Write(byte[])" />.
/// </summary> /// </summary>
/// <param name="stream">The stream to be written to</param> /// <param name="stream">The stream to be written to</param>
/// <param name="buffer">The buffer of values to be written</param> /// <param name="buffer">The buffer of values to be written</param>
-20
View File
@@ -53,9 +53,6 @@ namespace Ryujinx.Common
{ {
public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName) public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName)
{ {
if (eventArgs.AreValuesEqual)
return;
string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}"); string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}");
Logger.Info?.Print(logClass, message); Logger.Info?.Print(logClass, message);
@@ -68,22 +65,5 @@ namespace Ryujinx.Common
{ {
public T OldValue { get; } = oldValue; public T OldValue { get; } = oldValue;
public T NewValue { get; } = newValue; public T NewValue { get; } = newValue;
public bool AreValuesEqual
{
get
{
if (OldValue == null && NewValue == null)
return true;
if (OldValue == null && NewValue != null)
return false;
if (OldValue != null && NewValue == null)
return false;
return OldValue!.Equals(NewValue);
}
}
} }
} }
-4
View File
@@ -8,8 +8,6 @@ namespace Ryujinx.Common
{ {
public static class TitleIDs public static class TitleIDs
{ {
public static ReactiveObject<Optional<string>> CurrentApplication { get; set; } = new();
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend) public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
{ {
switch (currentBackend) switch (currentBackend)
@@ -35,8 +33,6 @@ namespace Ryujinx.Common
"010028600EBDA000", // Mario 3D World "010028600EBDA000", // Mario 3D World
"0100152000022000", // Mario Kart 8 Deluxe "0100152000022000", // Mario Kart 8 Deluxe
"01005CA01580E000", // Persona 5 "01005CA01580E000", // Persona 5
"0100187003A36000", // Pokémon: Let's Go, Evoli!
"010003f003a34000", // Pokémon: Let's Go, Pikachu!
"01008C0016544000", // Sea of Stars "01008C0016544000", // Sea of Stars
"01006A800016E000", // Smash Ultimate "01006A800016E000", // Smash Ultimate
"0100000000010000", // Super Mario Odyessy "0100000000010000", // Super Mario Odyessy
-30
View File
@@ -40,35 +40,5 @@ namespace Ryujinx.Common
return (value >> 32) | (value << 32); return (value >> 32) | (value << 32);
} }
// Never actually written bit packing logic before, so I looked it up.
// This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195
public static ulong PackBitFields(this uint[] values, byte[] bitFields)
{
ulong retVal = values[0]; //we set the first value right away
for (int f = 1; f < values.Length; f++)
{
retVal <<= bitFields[f]; // we shift the previous value
retVal += values[f];// and add our current value
}
return retVal;
}
public static uint[] UnpackBitFields(this ulong packed, byte[] bitFields)
{
int fields = bitFields.Length - 1; // number of fields to unpack
uint[] retArr = new uint[fields + 1]; // init return array
int curPos = 0; // current field bit position (start)
int lastEnd; // position where last field ended
for (int f = fields; f >= 0; f--) // loop from last
{
lastEnd = curPos; // we store where the last value ended
curPos += bitFields[f]; // we get where the current value starts
int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion
retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic
}
return retArr;
}
} }
} }
+1 -11
View File
@@ -1,5 +1,4 @@
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine.GPFifo; using Ryujinx.Graphics.Gpu.Engine.GPFifo;
@@ -91,13 +90,6 @@ namespace Ryujinx.Graphics.Gpu
/// Support buffer updater. /// Support buffer updater.
/// </summary> /// </summary>
internal SupportBufferUpdater SupportBufferUpdater { get; } internal SupportBufferUpdater SupportBufferUpdater { 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> /// <summary>
/// Host hardware capabilities. /// Host hardware capabilities.
@@ -121,7 +113,7 @@ namespace Ryujinx.Graphics.Gpu
/// Creates a new instance of the GPU emulation context. /// Creates a new instance of the GPU emulation context.
/// </summary> /// </summary>
/// <param name="renderer">Host renderer</param> /// <param name="renderer">Host renderer</param>
public GpuContext(IRenderer renderer, DirtyHacks hacks) public GpuContext(IRenderer renderer)
{ {
Renderer = renderer; Renderer = renderer;
@@ -144,8 +136,6 @@ namespace Ryujinx.Graphics.Gpu
SupportBufferUpdater = new SupportBufferUpdater(renderer); SupportBufferUpdater = new SupportBufferUpdater(renderer);
DirtyHacks = hacks;
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds); _firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
} }
+1 -1
View File
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Gpu
/// Enables or disables high-level emulation of common GPU Macro code. /// Enables or disables high-level emulation of common GPU Macro code.
/// </summary> /// </summary>
public static bool EnableMacroHLE = true; public static bool EnableMacroHLE = true;
/// <summary> /// <summary>
/// Title id of the current running game. /// Title id of the current running game.
/// Used by the shader cache. /// Used by the shader cache.
@@ -1,4 +1,3 @@
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader;
@@ -367,9 +366,6 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
{ {
try try
{ {
if (_context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay))
Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]);
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute); AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken); _asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
} }
@@ -1,4 +1,3 @@
using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
+13 -7
View File
@@ -22,15 +22,13 @@ namespace Ryujinx.Graphics.Metal
private int _requestedWidth; private int _requestedWidth;
private int _requestedHeight; private int _requestedHeight;
// private bool _vsyncEnabled;
private AntiAliasing _currentAntiAliasing; private AntiAliasing _currentAntiAliasing;
private bool _updateEffect; private bool _updateEffect;
private IPostProcessingEffect _effect; private IPostProcessingEffect _effect;
private IScalingFilter _scalingFilter; private IScalingFilter _scalingFilter;
private bool _isLinear; private bool _isLinear;
public bool IsVSyncEnabled => _metalLayer.DisplaySyncEnabled;
// private float _scalingFilterLevel; // private float _scalingFilterLevel;
private bool _updateScalingFilter; private bool _updateScalingFilter;
private ScalingFilter _currentScalingFilter; private ScalingFilter _currentScalingFilter;
@@ -42,7 +40,7 @@ namespace Ryujinx.Graphics.Metal
_metalLayer = metalLayer; _metalLayer = metalLayer;
} }
private void ResizeIfNeeded() private unsafe void ResizeIfNeeded()
{ {
if (_requestedWidth != 0 && _requestedHeight != 0) if (_requestedWidth != 0 && _requestedHeight != 0)
{ {
@@ -56,7 +54,7 @@ namespace Ryujinx.Graphics.Metal
} }
} }
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback) public unsafe void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
{ {
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex) if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
{ {
@@ -143,7 +141,15 @@ namespace Ryujinx.Graphics.Metal
public void ChangeVSyncMode(VSyncMode vSyncMode) public void ChangeVSyncMode(VSyncMode vSyncMode)
{ {
_metalLayer.DisplaySyncEnabled = vSyncMode is VSyncMode.Switch; switch (vSyncMode)
{
case VSyncMode.Unbounded:
_metalLayer.DisplaySyncEnabled = false;
break;
case VSyncMode.Switch:
_metalLayer.DisplaySyncEnabled = true;
break;
}
} }
public void SetAntiAliasing(AntiAliasing effect) public void SetAntiAliasing(AntiAliasing effect)
+3 -3
View File
@@ -2,8 +2,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
{ {
internal enum BitDepth internal enum BitDepth
{ {
Bits8 = 8, // < 8 bits Bits8 = 8, /**< 8 bits */
Bits10 = 10, // < 10 bits Bits10 = 10, /**< 10 bits */
Bits12 = 12, // < 12 bits Bits12 = 12, /**< 12 bits */
} }
} }
@@ -1,4 +1,3 @@
using Gommon;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
@@ -891,12 +890,7 @@ namespace Ryujinx.Graphics.Vulkan
private void PrintGpuInformation() private void PrintGpuInformation()
{ {
string gpuInfoMessage = $"{GpuRenderer} ({GpuVersion})"; Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
if (!GpuRenderer.StartsWithIgnoreCase(GpuVendor))
gpuInfoMessage = gpuInfoMessage.Prepend(GpuVendor);
Logger.Notice.Print(LogClass.Gpu, gpuInfoMessage);
Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB"); Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB");
} }
+1 -8
View File
@@ -188,11 +188,6 @@ namespace Ryujinx.HLE
/// An action called when HLE force a refresh of output after docked mode changed. /// An action called when HLE force a refresh of output after docked mode changed.
/// </summary> /// </summary>
public Action RefreshInputConfig { internal get; set; } public Action RefreshInputConfig { internal get; set; }
/// <summary>
/// The desired hacky workarounds.
/// </summary>
public EnabledDirtyHack[] Hacks { internal get; set; }
public HLEConfiguration(VirtualFileSystem virtualFileSystem, public HLEConfiguration(VirtualFileSystem virtualFileSystem,
LibHacHorizonManager libHacHorizonManager, LibHacHorizonManager libHacHorizonManager,
@@ -223,8 +218,7 @@ namespace Ryujinx.HLE
bool multiplayerDisableP2p, bool multiplayerDisableP2p,
string multiplayerLdnPassphrase, string multiplayerLdnPassphrase,
string multiplayerLdnServer, string multiplayerLdnServer,
int customVSyncInterval, int customVSyncInterval)
EnabledDirtyHack[] dirtyHacks = null)
{ {
VirtualFileSystem = virtualFileSystem; VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager; LibHacHorizonManager = libHacHorizonManager;
@@ -256,7 +250,6 @@ namespace Ryujinx.HLE
MultiplayerDisableP2p = multiplayerDisableP2p; MultiplayerDisableP2p = multiplayerDisableP2p;
MultiplayerLdnPassphrase = multiplayerLdnPassphrase; MultiplayerLdnPassphrase = multiplayerLdnPassphrase;
MultiplayerLdnServer = multiplayerLdnServer; MultiplayerLdnServer = multiplayerLdnServer;
Hacks = dirtyHacks ?? [];
} }
} }
} }
@@ -1,9 +1,6 @@
using LibHac; using LibHac;
using LibHac.Common; using LibHac.Common;
using LibHac.Sf; using LibHac.Sf;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{ {
@@ -16,8 +13,6 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
_baseStorage = SharedRef<LibHac.FsSrv.Sf.IStorage>.CreateMove(ref baseStorage); _baseStorage = SharedRef<LibHac.FsSrv.Sf.IStorage>.CreateMove(ref baseStorage);
} }
private const string Xc2TitleId = "0100e95004038000";
[CommandCmif(0)] [CommandCmif(0)]
// Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer // Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
public ResultCode Read(ServiceCtx context) public ResultCode Read(ServiceCtx context)
@@ -38,13 +33,6 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true); using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true);
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size); Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
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
Thread.Sleep(2);
}
return (ResultCode)result.Value; return (ResultCode)result.Value;
} }
@@ -114,10 +114,10 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption
} }
} }
string usedCharacterStr = Convert.ToHexString(usedCharacter); string usedCharacterStr = BitConverter.ToString(usedCharacter).Replace("-", "");
string variationStr = Convert.ToHexString(variation); string variationStr = BitConverter.ToString(variation).Replace("-", "");
string amiiboIDStr = Convert.ToHexString(amiiboID); string amiiboIDStr = BitConverter.ToString(amiiboID).Replace("-", "");
string setIDStr = Convert.ToHexString(setID); string setIDStr = BitConverter.ToString(setID).Replace("-", "");
string head = usedCharacterStr + variationStr; string head = usedCharacterStr + variationStr;
string tail = amiiboIDStr + setIDStr + "02"; string tail = amiiboIDStr + setIDStr + "02";
string finalID = head + tail; string finalID = head + tail;
@@ -289,8 +289,8 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption
private static void LogFinalData(byte[] titleId, byte[] appId, string head, string tail, string finalID, string nickName, DateTime initDateTime, DateTime writeDateTime, ushort settingsValue, ushort writeCounterValue, byte[] applicationAreas) private static void LogFinalData(byte[] titleId, byte[] appId, string head, string tail, string finalID, string nickName, DateTime initDateTime, DateTime writeDateTime, ushort settingsValue, ushort writeCounterValue, byte[] applicationAreas)
{ {
Logger.Debug?.Print(LogClass.ServiceNfp, $"Title ID: 0x{Convert.ToHexString(titleId)}"); Logger.Debug?.Print(LogClass.ServiceNfp, $"Title ID: 0x{BitConverter.ToString(titleId).Replace("-", "")}");
Logger.Debug?.Print(LogClass.ServiceNfp, $"Application Program ID: 0x{Convert.ToHexString(appId)}"); Logger.Debug?.Print(LogClass.ServiceNfp, $"Application Program ID: 0x{BitConverter.ToString(appId).Replace("-", "")}");
Logger.Debug?.Print(LogClass.ServiceNfp, $"Head: {head}"); Logger.Debug?.Print(LogClass.ServiceNfp, $"Head: {head}");
Logger.Debug?.Print(LogClass.ServiceNfp, $"Tail: {tail}"); Logger.Debug?.Print(LogClass.ServiceNfp, $"Tail: {tail}");
Logger.Debug?.Print(LogClass.ServiceNfp, $"Final ID: {finalID}"); Logger.Debug?.Print(LogClass.ServiceNfp, $"Final ID: {finalID}");
@@ -4,10 +4,8 @@ using LibHac.Fs.Fsa;
using LibHac.Loader; using LibHac.Loader;
using LibHac.Ns; using LibHac.Ns;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.Loaders.Executables; using Ryujinx.HLE.Loaders.Executables;
using Ryujinx.Memory; using Ryujinx.Memory;
using System; using System;
@@ -104,7 +102,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
} }
// Initialize GPU. // Initialize GPU.
GraphicsConfig.TitleId = programId.ToString("X16"); Graphics.Gpu.GraphicsConfig.TitleId = programId.ToString("X16");
device.Gpu.HostInitalized.Set(); device.Gpu.HostInitalized.Set();
if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible)) if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible))
@@ -6,9 +6,7 @@ using LibHac.Ns;
using LibHac.Tools.Fs; using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.Loaders.Executables; using Ryujinx.HLE.Loaders.Executables;
using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.HLE.Loaders.Processes.Extensions;
using System; using System;
@@ -61,8 +59,6 @@ namespace Ryujinx.HLE.Loaders.Processes
{ {
_latestPid = processResult.ProcessId; _latestPid = processResult.ProcessId;
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
return true; return true;
} }
} }
@@ -90,8 +86,6 @@ namespace Ryujinx.HLE.Loaders.Processes
{ {
_latestPid = processResult.ProcessId; _latestPid = processResult.ProcessId;
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
return true; return true;
} }
} }
@@ -119,8 +113,6 @@ namespace Ryujinx.HLE.Loaders.Processes
if (processResult.ProgramId > 0x01000000000007FF) if (processResult.ProgramId > 0x01000000000007FF)
{ {
_latestPid = processResult.ProcessId; _latestPid = processResult.ProcessId;
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
} }
return true; return true;
@@ -140,8 +132,6 @@ namespace Ryujinx.HLE.Loaders.Processes
{ {
_latestPid = processResult.ProcessId; _latestPid = processResult.ProcessId;
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
return true; return true;
} }
} }
@@ -193,17 +183,14 @@ namespace Ryujinx.HLE.Loaders.Processes
if (nacpData.Value.PresenceGroupId != 0) if (nacpData.Value.PresenceGroupId != 0)
{ {
programId = nacpData.Value.PresenceGroupId; programId = nacpData.Value.PresenceGroupId;
TitleIDs.CurrentApplication.Value = programId.ToString("X16");
} }
else if (nacpData.Value.SaveDataOwnerId != 0) else if (nacpData.Value.SaveDataOwnerId != 0)
{ {
programId = nacpData.Value.SaveDataOwnerId; programId = nacpData.Value.SaveDataOwnerId;
TitleIDs.CurrentApplication.Value = programId.ToString("X16");
} }
else if (nacpData.Value.AddOnContentBaseId != 0) else if (nacpData.Value.AddOnContentBaseId != 0)
{ {
programId = nacpData.Value.AddOnContentBaseId - 0x1000; programId = nacpData.Value.AddOnContentBaseId - 0x1000;
TitleIDs.CurrentApplication.Value = programId.ToString("X16");
} }
} }
@@ -217,7 +204,7 @@ namespace Ryujinx.HLE.Loaders.Processes
} }
// Explicitly null TitleId to disable the shader cache. // Explicitly null TitleId to disable the shader cache.
GraphicsConfig.TitleId = null; Graphics.Gpu.GraphicsConfig.TitleId = null;
_device.Gpu.HostInitalized.Set(); _device.Gpu.HostInitalized.Set();
ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device, ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device,
+1 -13
View File
@@ -2,7 +2,6 @@ using LibHac.Common;
using LibHac.Ns; using LibHac.Ns;
using Ryujinx.Audio.Backends.CompatLayer; using Ryujinx.Audio.Backends.CompatLayer;
using Ryujinx.Audio.Integration; using Ryujinx.Audio.Integration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
@@ -18,8 +17,6 @@ namespace Ryujinx.HLE
{ {
public class Switch : IDisposable public class Switch : IDisposable
{ {
public static Switch Shared { get; private set; }
public HLEConfiguration Configuration { get; } public HLEConfiguration Configuration { get; }
public IHardwareDeviceDriver AudioDeviceDriver { get; } public IHardwareDeviceDriver AudioDeviceDriver { get; }
public MemoryBlock Memory { get; } public MemoryBlock Memory { get; }
@@ -40,8 +37,6 @@ namespace Ryujinx.HLE
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable; public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
public DirtyHacks DirtyHacks { get; }
public Switch(HLEConfiguration configuration) public Switch(HLEConfiguration configuration)
{ {
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer); ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
@@ -57,10 +52,9 @@ namespace Ryujinx.HLE
: MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable; : MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable;
#pragma warning disable IDE0055 // Disable formatting #pragma warning disable IDE0055 // Disable formatting
DirtyHacks = new DirtyHacks(Configuration.Hacks);
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver); AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags); Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks); Gpu = new GpuContext(Configuration.GpuRenderer);
System = new HOS.Horizon(this); System = new HOS.Horizon(this);
Statistics = new PerformanceStatistics(); Statistics = new PerformanceStatistics();
Hid = new Hid(this, System.HidStorage); Hid = new Hid(this, System.HidStorage);
@@ -78,11 +72,8 @@ namespace Ryujinx.HLE
System.EnablePtc = Configuration.EnablePtc; System.EnablePtc = Configuration.EnablePtc;
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel; System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode; System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
UpdateVSyncInterval(); UpdateVSyncInterval();
#pragma warning restore IDE0055 #pragma warning restore IDE0055
Shared = this;
} }
public void ProcessFrame() public void ProcessFrame()
@@ -151,9 +142,6 @@ namespace Ryujinx.HLE
AudioDeviceDriver.Dispose(); AudioDeviceDriver.Dispose();
FileSystem.Dispose(); FileSystem.Dispose();
Memory.Dispose(); Memory.Dispose();
TitleIDs.CurrentApplication.Value = null;
Shared = null;
} }
} }
} }
@@ -1,6 +1,6 @@
using System; using System;
namespace Ryujinx.Ava.Utilities.AppLibrary namespace Ryujinx.UI.App.Common
{ {
public class ApplicationCountUpdatedEventArgs : EventArgs public class ApplicationCountUpdatedEventArgs : EventArgs
{ {
@@ -10,14 +10,17 @@ using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.HLE.Loaders.Processes.Extensions;
using Ryujinx.UI.Common.Helper;
using System; using System;
using System.IO; using System.IO;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.AppLibrary namespace Ryujinx.UI.App.Common
{ {
public class ApplicationData public class ApplicationData
{ {
public static Func<string> LocalizedNever { get; set; } = () => "Never";
public bool Favorite { get; set; } public bool Favorite { get; set; }
public byte[] Icon { get; set; } public byte[] Icon { get; set; }
public string Name { get; set; } = "Unknown"; public string Name { get; set; } = "Unknown";
@@ -33,11 +36,11 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
public string Path { get; set; } public string Path { get; set; }
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; } public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0 && !ControlHolder.ByteSpan.IsZeros(); public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0;
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed); public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n"); public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n") ?? LocalizedNever();
public string FileSizeString => ValueFormatUtils.FormatFileSize(FileSize); public string FileSizeString => ValueFormatUtils.FormatFileSize(FileSize);
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.AppLibrary namespace Ryujinx.UI.App.Common
{ {
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ApplicationMetadata))] [JsonSerializable(typeof(ApplicationMetadata))]
@@ -10,10 +10,6 @@ using LibHac.Ns;
using LibHac.Tools.Fs; using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
@@ -23,11 +19,16 @@ using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Loaders.Npdm; using Ryujinx.HLE.Loaders.Npdm;
using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.HLE.Loaders.Processes.Extensions;
using Ryujinx.HLE.Utilities; using Ryujinx.HLE.Utilities;
using Ryujinx.UI.Common.Configuration;
using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.UI.Common.Helper;
using Ryujinx.UI.Common.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Reflection;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Threading; using System.Threading;
@@ -37,7 +38,7 @@ using MissingKeyException = LibHac.Common.Keys.MissingKeyException;
using Path = System.IO.Path; using Path = System.IO.Path;
using TimeSpan = System.TimeSpan; using TimeSpan = System.TimeSpan;
namespace Ryujinx.Ava.Utilities.AppLibrary namespace Ryujinx.UI.App.Common
{ {
public class ApplicationLibrary public class ApplicationLibrary
{ {
@@ -75,11 +76,21 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
TitleUpdates = _titleUpdates.AsObservableCache(); TitleUpdates = _titleUpdates.AsObservableCache();
DownloadableContents = _downloadableContents.AsObservableCache(); DownloadableContents = _downloadableContents.AsObservableCache();
_nspIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NSP.png"); _nspIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NSP.png");
_xciIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_XCI.png"); _xciIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_XCI.png");
_ncaIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NCA.png"); _ncaIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NCA.png");
_nroIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NRO.png"); _nroIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NRO.png");
_nsoIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NSO.png"); _nsoIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NSO.png");
}
private static byte[] GetResourceBytes(string resourceName)
{
Stream resourceStream = Assembly.GetCallingAssembly().GetManifestResourceStream(resourceName)!;
byte[] resourceByteArray = new byte[resourceStream.Length];
resourceStream.ReadExactly(resourceByteArray);
return resourceByteArray;
} }
/// <exception cref="Ryujinx.HLE.Exceptions.InvalidNpdmException">The npdm file doesn't contain valid data.</exception> /// <exception cref="Ryujinx.HLE.Exceptions.InvalidNpdmException">The npdm file doesn't contain valid data.</exception>
@@ -1,7 +1,7 @@
using System; using System;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.AppLibrary namespace Ryujinx.UI.App.Common
{ {
public class ApplicationMetadata public class ApplicationMetadata
{ {
@@ -1,10 +1,9 @@
using Gommon;
using LibHac.Ns; using LibHac.Ns;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Ryujinx.Ava.Utilities.AppLibrary namespace Ryujinx.UI.App.Common
{ {
public struct LdnGameData public struct LdnGameData
{ {
@@ -23,7 +22,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
LibHac.Common.FixedArrays.Array8<ulong> communicationId = acp.LocalCommunicationId; LibHac.Common.FixedArrays.Array8<ulong> communicationId = acp.LocalCommunicationId;
return new Array(receivedData.Where(game => return new Array(receivedData.Where(game =>
communicationId.Items.Contains(game.TitleId.ToULong()) communicationId.Items.Contains(Convert.ToUInt64(game.TitleId, 16))
)); ));
} }
@@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Ryujinx.Ava.Utilities.AppLibrary namespace Ryujinx.UI.App.Common
{ {
public class LdnGameDataReceivedEventArgs : EventArgs public class LdnGameDataReceivedEventArgs : EventArgs
{ {
@@ -1,8 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.AppLibrary namespace Ryujinx.UI.App.Common
{ {
[JsonSerializable(typeof(IEnumerable<LdnGameData>))] [JsonSerializable(typeof(IEnumerable<LdnGameData>))]
internal partial class LdnGameDataSerializerContext : JsonSerializerContext; internal partial class LdnGameDataSerializerContext : JsonSerializerContext
{
}
} }
@@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.Configuration namespace Ryujinx.UI.Common.Configuration
{ {
[JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))] [JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))]
public enum AudioBackend public enum AudioBackend
@@ -1,5 +1,3 @@
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
@@ -7,17 +5,19 @@ using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.UI.Common.Configuration.UI;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Nodes; using System.Text.Json.Nodes;
namespace Ryujinx.Ava.Utilities.Configuration namespace Ryujinx.UI.Common.Configuration
{ {
public class ConfigurationFileFormat public class ConfigurationFileFormat
{ {
/// <summary> /// <summary>
/// The current version of the file format /// The current version of the file format
/// </summary> /// </summary>
public const int CurrentVersion = 59; public const int CurrentVersion = 57;
/// <summary> /// <summary>
/// Version of the configuration file format /// Version of the configuration file format
@@ -272,7 +272,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
public MemoryManagerMode MemoryManagerMode { get; set; } public MemoryManagerMode MemoryManagerMode { get; set; }
/// <summary> /// <summary>
/// Expands the RAM amount on the emulated system /// Expands the RAM amount on the emulated system from 4GiB to 8GiB
/// </summary> /// </summary>
public MemoryConfiguration DramSize { get; set; } public MemoryConfiguration DramSize { get; set; }
@@ -429,17 +429,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// Uses Hypervisor over JIT if available /// Uses Hypervisor over JIT if available
/// </summary> /// </summary>
public bool UseHypervisor { get; set; } public bool UseHypervisor { get; set; }
/// <summary>
/// Show toggles for dirty hacks in the UI.
/// </summary>
public bool ShowDirtyHacks { get; set; }
/// <summary>
/// The packed values of the enabled dirty hacks.
/// </summary>
public ulong[] DirtyHacks { get; set; }
/// <summary> /// <summary>
/// Loads a configuration file from disk /// Loads a configuration file from disk
/// </summary> /// </summary>
@@ -1,6 +1,6 @@
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
namespace Ryujinx.Ava.Utilities.Configuration namespace Ryujinx.UI.Common.Configuration
{ {
internal static class ConfigurationFileFormatSettings internal static class ConfigurationFileFormatSettings
{ {
@@ -1,8 +1,10 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.Configuration namespace Ryujinx.UI.Common.Configuration
{ {
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ConfigurationFileFormat))] [JsonSerializable(typeof(ConfigurationFileFormat))]
internal partial class ConfigurationJsonSerializerContext : JsonSerializerContext; internal partial class ConfigurationJsonSerializerContext : JsonSerializerContext
{
}
} }
@@ -0,0 +1,747 @@
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.Logging;
using Ryujinx.HLE;
using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.UI.Common.Configuration.UI;
using System;
using System.Collections.Generic;
namespace Ryujinx.UI.Common.Configuration
{
public partial class ConfigurationState
{
public void Load(ConfigurationFileFormat configurationFileFormat, string configurationFilePath)
{
bool configurationFileUpdated = false;
if (configurationFileFormat.Version is < 0 or > ConfigurationFileFormat.CurrentVersion)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Unsupported configuration version {configurationFileFormat.Version}, loading default.");
LoadDefault();
}
if (configurationFileFormat.Version < 2)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 2.");
configurationFileFormat.SystemRegion = Region.USA;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 3)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 3.");
configurationFileFormat.SystemTimeZone = "UTC";
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 4)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 4.");
configurationFileFormat.MaxAnisotropy = -1;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 5)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 5.");
configurationFileFormat.SystemTimeOffset = 0;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 8)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 8.");
configurationFileFormat.EnablePtc = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 9)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 9.");
configurationFileFormat.ColumnSort = new ColumnSort
{
SortColumnId = 0,
SortAscending = false,
};
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = Key.F1,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 10)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 10.");
configurationFileFormat.AudioBackend = AudioBackend.OpenAl;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 11)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 11.");
configurationFileFormat.ResScale = 1;
configurationFileFormat.ResScaleCustom = 1.0f;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 12)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 12.");
configurationFileFormat.LoggingGraphicsDebugLevel = GraphicsDebugLevel.None;
configurationFileUpdated = true;
}
// configurationFileFormat.Version == 13 -> LDN1
if (configurationFileFormat.Version < 14)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 14.");
configurationFileFormat.CheckUpdatesOnStart = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 16)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 16.");
configurationFileFormat.EnableShaderCache = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 17)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 17.");
configurationFileFormat.StartFullscreen = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 18)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 18.");
configurationFileFormat.AspectRatio = AspectRatio.Fixed16x9;
configurationFileUpdated = true;
}
// configurationFileFormat.Version == 19 -> LDN2
if (configurationFileFormat.Version < 20)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 20.");
configurationFileFormat.ShowConfirmExit = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 21)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 21.");
// Initialize network config.
configurationFileFormat.MultiplayerMode = MultiplayerMode.Disabled;
configurationFileFormat.MultiplayerLanInterfaceId = "0";
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 22)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 22.");
configurationFileFormat.HideCursor = HideCursorMode.Never;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 24)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 24.");
configurationFileFormat.InputConfig = new List<InputConfig>
{
new StandardKeyboardInputConfig
{
Version = InputConfig.CurrentVersion,
Backend = InputBackendType.WindowKeyboard,
Id = "0",
PlayerIndex = PlayerIndex.Player1,
ControllerType = ControllerType.ProController,
LeftJoycon = new LeftJoyconCommonConfig<Key>
{
DpadUp = Key.Up,
DpadDown = Key.Down,
DpadLeft = Key.Left,
DpadRight = Key.Right,
ButtonMinus = Key.Minus,
ButtonL = Key.E,
ButtonZl = Key.Q,
ButtonSl = Key.Unbound,
ButtonSr = Key.Unbound,
},
LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
{
StickUp = Key.W,
StickDown = Key.S,
StickLeft = Key.A,
StickRight = Key.D,
StickButton = Key.F,
},
RightJoycon = new RightJoyconCommonConfig<Key>
{
ButtonA = Key.Z,
ButtonB = Key.X,
ButtonX = Key.C,
ButtonY = Key.V,
ButtonPlus = Key.Plus,
ButtonR = Key.U,
ButtonZr = Key.O,
ButtonSl = Key.Unbound,
ButtonSr = Key.Unbound,
},
RightJoyconStick = new JoyconConfigKeyboardStick<Key>
{
StickUp = Key.I,
StickDown = Key.K,
StickLeft = Key.J,
StickRight = Key.L,
StickButton = Key.H,
},
},
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 25)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 25.");
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 26)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 26.");
configurationFileFormat.MemoryManagerMode = MemoryManagerMode.HostMappedUnsafe;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 27)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 27.");
configurationFileFormat.EnableMouse = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 28)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 28.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = Key.F1,
Screenshot = Key.F8,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 29)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 29.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = Key.F1,
Screenshot = Key.F8,
ShowUI = Key.F4,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 30)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 30.");
foreach (InputConfig config in configurationFileFormat.InputConfig)
{
if (config is StandardControllerInputConfig controllerConfig)
{
controllerConfig.Rumble = new RumbleConfigController
{
EnableRumble = false,
StrongRumble = 1f,
WeakRumble = 1f,
};
}
}
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 31)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 31.");
configurationFileFormat.BackendThreading = BackendThreading.Auto;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 32)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 32.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = Key.F5,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 33)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 33.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
ToggleMute = Key.F2,
};
configurationFileFormat.AudioVolume = 1;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 34)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 34.");
configurationFileFormat.EnableInternetAccess = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 35)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 35.");
foreach (InputConfig config in configurationFileFormat.InputConfig)
{
if (config is StandardControllerInputConfig controllerConfig)
{
controllerConfig.RangeLeft = 1.0f;
controllerConfig.RangeRight = 1.0f;
}
}
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 36)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 36.");
configurationFileFormat.LoggingEnableTrace = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 37)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 37.");
configurationFileFormat.ShowConsole = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 38)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 38.");
configurationFileFormat.BaseStyle = "Dark";
configurationFileFormat.GameListViewMode = 0;
configurationFileFormat.ShowNames = true;
configurationFileFormat.GridSize = 2;
configurationFileFormat.LanguageCode = "en_US";
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 39)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 39.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
ResScaleUp = Key.Unbound,
ResScaleDown = Key.Unbound,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 40)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 40.");
configurationFileFormat.GraphicsBackend = GraphicsBackend.OpenGl;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 41)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 41.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
VolumeUp = Key.Unbound,
VolumeDown = Key.Unbound,
};
}
if (configurationFileFormat.Version < 42)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 42.");
configurationFileFormat.EnableMacroHLE = true;
}
if (configurationFileFormat.Version < 43)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 43.");
configurationFileFormat.UseHypervisor = true;
}
if (configurationFileFormat.Version < 44)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 44.");
configurationFileFormat.AntiAliasing = AntiAliasing.None;
configurationFileFormat.ScalingFilter = ScalingFilter.Bilinear;
configurationFileFormat.ScalingFilterLevel = 80;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 45)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 45.");
configurationFileFormat.ShownFileTypes = new ShownFileTypes
{
NSP = true,
PFS0 = true,
XCI = true,
NCA = true,
NRO = true,
NSO = true,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 46)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 46.");
configurationFileFormat.MultiplayerLanInterfaceId = "0";
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 47)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 47.");
configurationFileFormat.WindowStartup = new WindowStartup
{
WindowPositionX = 0,
WindowPositionY = 0,
WindowSizeHeight = 760,
WindowSizeWidth = 1280,
WindowMaximized = false,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 48)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 48.");
configurationFileFormat.EnableColorSpacePassthrough = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 49)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 49.");
if (OperatingSystem.IsMacOS())
{
AppDataManager.FixMacOSConfigurationFolders();
}
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 50)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 50.");
configurationFileFormat.EnableHardwareAcceleration = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 51)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 51.");
configurationFileFormat.RememberWindowState = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 52)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 52.");
configurationFileFormat.AutoloadDirs = [];
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 53)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 53.");
configurationFileFormat.EnableLowPowerPtc = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 54)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 54.");
configurationFileFormat.DramSize = MemoryConfiguration.MemoryConfiguration4GiB;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 55)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 55.");
configurationFileFormat.IgnoreApplet = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 56)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 56.");
configurationFileFormat.ShowTitleBar = !OperatingSystem.IsWindows();
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 57)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 57.");
configurationFileFormat.VSyncMode = VSyncMode.Switch;
configurationFileFormat.EnableCustomVSyncInterval = false;
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = Key.F1,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
VolumeUp = configurationFileFormat.Hotkeys.VolumeUp,
VolumeDown = configurationFileFormat.Hotkeys.VolumeDown,
CustomVSyncIntervalIncrement = Key.Unbound,
CustomVSyncIntervalDecrement = Key.Unbound,
};
configurationFileFormat.CustomVSyncInterval = 120;
configurationFileUpdated = true;
}
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.ResScale.Value = configurationFileFormat.ResScale;
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
Graphics.MaxAnisotropy.Value = configurationFileFormat.MaxAnisotropy;
Graphics.AspectRatio.Value = configurationFileFormat.AspectRatio;
Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
Graphics.GraphicsBackend.Value = configurationFileFormat.GraphicsBackend;
Graphics.PreferredGpu.Value = configurationFileFormat.PreferredGpu;
Graphics.AntiAliasing.Value = configurationFileFormat.AntiAliasing;
Graphics.ScalingFilter.Value = configurationFileFormat.ScalingFilter;
Graphics.ScalingFilterLevel.Value = configurationFileFormat.ScalingFilterLevel;
Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
Logger.EnableStub.Value = configurationFileFormat.LoggingEnableStub;
Logger.EnableInfo.Value = configurationFileFormat.LoggingEnableInfo;
Logger.EnableWarn.Value = configurationFileFormat.LoggingEnableWarn;
Logger.EnableError.Value = configurationFileFormat.LoggingEnableError;
Logger.EnableTrace.Value = configurationFileFormat.LoggingEnableTrace;
Logger.EnableGuest.Value = configurationFileFormat.LoggingEnableGuest;
Logger.EnableFsAccessLog.Value = configurationFileFormat.LoggingEnableFsAccessLog;
Logger.FilteredClasses.Value = configurationFileFormat.LoggingFilteredClasses;
Logger.GraphicsDebugLevel.Value = configurationFileFormat.LoggingGraphicsDebugLevel;
System.Language.Value = configurationFileFormat.SystemLanguage;
System.Region.Value = configurationFileFormat.SystemRegion;
System.TimeZone.Value = configurationFileFormat.SystemTimeZone;
System.SystemTimeOffset.Value = configurationFileFormat.SystemTimeOffset;
System.EnableDockedMode.Value = configurationFileFormat.DockedMode;
EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;
IgnoreApplet.Value = configurationFileFormat.IgnoreApplet;
RememberWindowState.Value = configurationFileFormat.RememberWindowState;
ShowTitleBar.Value = configurationFileFormat.ShowTitleBar;
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
HideCursor.Value = configurationFileFormat.HideCursor;
Graphics.VSyncMode.Value = configurationFileFormat.VSyncMode;
Graphics.EnableCustomVSyncInterval.Value = configurationFileFormat.EnableCustomVSyncInterval;
Graphics.CustomVSyncInterval.Value = configurationFileFormat.CustomVSyncInterval;
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression;
Graphics.EnableMacroHLE.Value = configurationFileFormat.EnableMacroHLE;
Graphics.EnableColorSpacePassthrough.Value = configurationFileFormat.EnableColorSpacePassthrough;
System.EnablePtc.Value = configurationFileFormat.EnablePtc;
System.EnableLowPowerPtc.Value = configurationFileFormat.EnableLowPowerPtc;
System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess;
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
System.AudioBackend.Value = configurationFileFormat.AudioBackend;
System.AudioVolume.Value = configurationFileFormat.AudioVolume;
System.MemoryManagerMode.Value = configurationFileFormat.MemoryManagerMode;
System.DramSize.Value = configurationFileFormat.DramSize;
System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
System.UseHypervisor.Value = configurationFileFormat.UseHypervisor;
UI.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
UI.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
UI.GuiColumns.AppColumn.Value = configurationFileFormat.GuiColumns.AppColumn;
UI.GuiColumns.DevColumn.Value = configurationFileFormat.GuiColumns.DevColumn;
UI.GuiColumns.VersionColumn.Value = configurationFileFormat.GuiColumns.VersionColumn;
UI.GuiColumns.TimePlayedColumn.Value = configurationFileFormat.GuiColumns.TimePlayedColumn;
UI.GuiColumns.LastPlayedColumn.Value = configurationFileFormat.GuiColumns.LastPlayedColumn;
UI.GuiColumns.FileExtColumn.Value = configurationFileFormat.GuiColumns.FileExtColumn;
UI.GuiColumns.FileSizeColumn.Value = configurationFileFormat.GuiColumns.FileSizeColumn;
UI.GuiColumns.PathColumn.Value = configurationFileFormat.GuiColumns.PathColumn;
UI.ColumnSort.SortColumnId.Value = configurationFileFormat.ColumnSort.SortColumnId;
UI.ColumnSort.SortAscending.Value = configurationFileFormat.ColumnSort.SortAscending;
UI.GameDirs.Value = configurationFileFormat.GameDirs;
UI.AutoloadDirs.Value = configurationFileFormat.AutoloadDirs ?? [];
UI.ShownFileTypes.NSP.Value = configurationFileFormat.ShownFileTypes.NSP;
UI.ShownFileTypes.PFS0.Value = configurationFileFormat.ShownFileTypes.PFS0;
UI.ShownFileTypes.XCI.Value = configurationFileFormat.ShownFileTypes.XCI;
UI.ShownFileTypes.NCA.Value = configurationFileFormat.ShownFileTypes.NCA;
UI.ShownFileTypes.NRO.Value = configurationFileFormat.ShownFileTypes.NRO;
UI.ShownFileTypes.NSO.Value = configurationFileFormat.ShownFileTypes.NSO;
UI.LanguageCode.Value = configurationFileFormat.LanguageCode;
UI.BaseStyle.Value = configurationFileFormat.BaseStyle;
UI.GameListViewMode.Value = configurationFileFormat.GameListViewMode;
UI.ShowNames.Value = configurationFileFormat.ShowNames;
UI.IsAscendingOrder.Value = configurationFileFormat.IsAscendingOrder;
UI.GridSize.Value = configurationFileFormat.GridSize;
UI.ApplicationSort.Value = configurationFileFormat.ApplicationSort;
UI.StartFullscreen.Value = configurationFileFormat.StartFullscreen;
UI.ShowConsole.Value = configurationFileFormat.ShowConsole;
UI.WindowStartup.WindowSizeWidth.Value = configurationFileFormat.WindowStartup.WindowSizeWidth;
UI.WindowStartup.WindowSizeHeight.Value = configurationFileFormat.WindowStartup.WindowSizeHeight;
UI.WindowStartup.WindowPositionX.Value = configurationFileFormat.WindowStartup.WindowPositionX;
UI.WindowStartup.WindowPositionY.Value = configurationFileFormat.WindowStartup.WindowPositionY;
UI.WindowStartup.WindowMaximized.Value = configurationFileFormat.WindowStartup.WindowMaximized;
Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
Hid.EnableMouse.Value = configurationFileFormat.EnableMouse;
Hid.Hotkeys.Value = configurationFileFormat.Hotkeys;
Hid.InputConfig.Value = configurationFileFormat.InputConfig ?? [];
Multiplayer.LanInterfaceId.Value = configurationFileFormat.MultiplayerLanInterfaceId;
Multiplayer.Mode.Value = configurationFileFormat.MultiplayerMode;
Multiplayer.DisableP2p.Value = configurationFileFormat.MultiplayerDisableP2p;
Multiplayer.LdnPassphrase.Value = configurationFileFormat.MultiplayerLdnPassphrase;
Multiplayer.LdnServer.Value = configurationFileFormat.LdnServer;
if (configurationFileUpdated)
{
ToFileFormat().SaveConfig(configurationFilePath);
Ryujinx.Common.Logging.Logger.Notice.Print(LogClass.Application, $"Configuration file updated to version {ConfigurationFileFormat.CurrentVersion}");
}
}
}
}
@@ -1,18 +1,15 @@
using ARMeilleure; using ARMeilleure;
using Gommon;
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.Helper;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.UI.Common.Helper;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using RyuLogger = Ryujinx.Common.Logging.Logger;
namespace Ryujinx.Ava.Utilities.Configuration namespace Ryujinx.UI.Common.Configuration
{ {
public partial class ConfigurationState public partial class ConfigurationState
{ {
@@ -620,70 +617,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
} }
} }
public class HacksSection
{
/// <summary>
/// Show toggles for dirty hacks in the UI.
/// </summary>
public ReactiveObject<bool> ShowDirtyHacks { get; private set; }
public ReactiveObject<bool> Xc2MenuSoftlockFix { get; private set; }
public ReactiveObject<bool> EnableShaderTranslationDelay { get; private set; }
public ReactiveObject<int> ShaderTranslationDelay { get; private set; }
public HacksSection()
{
ShowDirtyHacks = new ReactiveObject<bool>();
Xc2MenuSoftlockFix = new ReactiveObject<bool>();
Xc2MenuSoftlockFix.Event += HackChanged;
EnableShaderTranslationDelay = new ReactiveObject<bool>();
EnableShaderTranslationDelay.Event += HackChanged;
ShaderTranslationDelay = new ReactiveObject<int>();
}
private void HackChanged(object sender, ReactiveEventArgs<bool> rxe)
{
if (!ShowDirtyHacks)
return;
var newHacks = EnabledHacks.Select(x => x.Hack)
.JoinToString(", ");
if (newHacks != _lastHackCollection)
{
RyuLogger.Info?.Print(LogClass.Configuration,
$"EnabledDirtyHacks set to: [{newHacks}]", "LogValueChange");
_lastHackCollection = newHacks;
}
}
private static string _lastHackCollection;
public EnabledDirtyHack[] EnabledHacks
{
get
{
List<EnabledDirtyHack> enabledHacks = [];
if (Xc2MenuSoftlockFix)
Apply(DirtyHack.Xc2MenuSoftlockFix);
if (EnableShaderTranslationDelay)
Apply(DirtyHack.ShaderTranslationDelay, ShaderTranslationDelay);
return enabledHacks.ToArray();
void Apply(DirtyHack hack, int value = 0)
{
enabledHacks.Add(new EnabledDirtyHack(hack, value));
}
}
}
}
/// <summary> /// <summary>
/// The default configuration instance /// The default configuration instance
/// </summary> /// </summary>
@@ -718,11 +651,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// The Multiplayer section /// The Multiplayer section
/// </summary> /// </summary>
public MultiplayerSection Multiplayer { get; private set; } public MultiplayerSection Multiplayer { get; private set; }
/// <summary>
/// The Dirty Hacks section
/// </summary>
public HacksSection Hacks { get; private set; }
/// <summary> /// <summary>
/// Enables or disables Discord Rich Presence /// Enables or disables Discord Rich Presence
@@ -772,7 +700,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
Graphics = new GraphicsSection(); Graphics = new GraphicsSection();
Hid = new HidSection(); Hid = new HidSection();
Multiplayer = new MultiplayerSection(); Multiplayer = new MultiplayerSection();
Hacks = new HacksSection();
EnableDiscordIntegration = new ReactiveObject<bool>(); EnableDiscordIntegration = new ReactiveObject<bool>();
CheckUpdatesOnStart = new ReactiveObject<bool>(); CheckUpdatesOnStart = new ReactiveObject<bool>();
ShowConfirmExit = new ReactiveObject<bool>(); ShowConfirmExit = new ReactiveObject<bool>();
@@ -1,15 +1,14 @@
using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Graphics.Vulkan; using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.UI.Common.Configuration.UI;
using System; using System;
using System.Linq;
namespace Ryujinx.Ava.Utilities.Configuration namespace Ryujinx.UI.Common.Configuration
{ {
public partial class ConfigurationState public partial class ConfigurationState
{ {
@@ -139,8 +138,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
MultiplayerDisableP2p = Multiplayer.DisableP2p, MultiplayerDisableP2p = Multiplayer.DisableP2p,
MultiplayerLdnPassphrase = Multiplayer.LdnPassphrase, MultiplayerLdnPassphrase = Multiplayer.LdnPassphrase,
LdnServer = Multiplayer.LdnServer, LdnServer = Multiplayer.LdnServer,
ShowDirtyHacks = Hacks.ShowDirtyHacks,
DirtyHacks = Hacks.EnabledHacks.Select(it => it.Pack()).ToArray(),
}; };
return configurationFile; return configurationFile;
@@ -0,0 +1,12 @@
namespace Ryujinx.UI.Common
{
public enum FileTypes
{
NSP,
PFS0,
XCI,
NCA,
NRO,
NSO
}
}
@@ -4,7 +4,7 @@ using Ryujinx.Common.Logging.Targets;
using System; using System;
using System.IO; using System.IO;
namespace Ryujinx.Ava.Utilities.Configuration namespace Ryujinx.UI.Common.Configuration
{ {
public static class LoggerModule public static class LoggerModule
{ {
@@ -1,7 +1,8 @@
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS.SystemState;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.Configuration.System namespace Ryujinx.UI.Common.Configuration.System
{ {
[JsonConverter(typeof(TypedStringEnumConverter<Language>))] [JsonConverter(typeof(TypedStringEnumConverter<Language>))]
public enum Language public enum Language
@@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.Configuration.System namespace Ryujinx.UI.Common.Configuration.System
{ {
[JsonConverter(typeof(TypedStringEnumConverter<Region>))] [JsonConverter(typeof(TypedStringEnumConverter<Region>))]
public enum Region public enum Region
@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Utilities.Configuration.UI namespace Ryujinx.UI.Common.Configuration.UI
{ {
public struct ColumnSort public struct ColumnSort
{ {
@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Utilities.Configuration.UI namespace Ryujinx.UI.Common.Configuration.UI
{ {
public struct GuiColumns public struct GuiColumns
{ {
@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Utilities.Configuration.UI namespace Ryujinx.UI.Common.Configuration.UI
{ {
public struct ShownFileTypes public struct ShownFileTypes
{ {
@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Utilities.Configuration.UI namespace Ryujinx.UI.Common.Configuration.UI
{ {
public struct WindowStartup public struct WindowStartup
{ {
@@ -1,14 +1,13 @@
using DiscordRPC; using DiscordRPC;
using Humanizer; using Humanizer;
using Humanizer.Localisation; using Humanizer.Localisation;
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.HLE;
using Ryujinx.HLE.Loaders.Processes; using Ryujinx.HLE.Loaders.Processes;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Configuration;
using System.Text; using System.Text;
namespace Ryujinx.Ava namespace Ryujinx.UI.Common
{ {
public static class DiscordIntegrationModule public static class DiscordIntegrationModule
{ {
@@ -45,16 +44,6 @@ namespace Ryujinx.Ava
}; };
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update; ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
TitleIDs.CurrentApplication.Event += (_, e) =>
{
if (e.NewValue)
SwitchToPlayingState(
ApplicationLibrary.LoadAndSaveMetaData(e.NewValue),
Switch.Shared.Processes.ActiveApplication
);
else
SwitchToMainState();
};
} }
private static void Update(object sender, ReactiveEventArgs<bool> evnt) private static void Update(object sender, ReactiveEventArgs<bool> evnt)
@@ -80,7 +69,7 @@ namespace Ryujinx.Ava
} }
} }
private static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes) public static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes)
{ {
_discordClient?.SetPresence(new RichPresence _discordClient?.SetPresence(new RichPresence
{ {
@@ -99,7 +88,7 @@ namespace Ryujinx.Ava
}); });
} }
private static void SwitchToMainState() => _discordClient?.SetPresence(_discordPresenceMain); public static void SwitchToMainState() => _discordClient?.SetPresence(_discordPresenceMain);
private static string TruncateToByteLength(string input) private static string TruncateToByteLength(string input)
{ {
@@ -1,19 +1,8 @@
using System; using System;
using static Ryujinx.UI.Common.Configuration.ConfigurationState.UISection;
using static Ryujinx.Ava.Utilities.Configuration.ConfigurationState.UISection; namespace Ryujinx.UI.Common
namespace Ryujinx.Ava.Utilities.Configuration
{ {
public enum FileTypes
{
NSP,
PFS0,
XCI,
NCA,
NRO,
NSO
}
public static class FileTypesExtensions public static class FileTypesExtensions
{ {
/// <summary> /// <summary>
@@ -21,7 +10,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// </summary> /// </summary>
/// <param name="type">The name of the <see cref="ShownFileTypeSettings"/> parameter to get the value of.</param> /// <param name="type">The name of the <see cref="ShownFileTypeSettings"/> parameter to get the value of.</param>
/// <param name="config">The config instance to get the value from.</param> /// <param name="config">The config instance to get the value from.</param>
/// <returns>The current value of the setting. Value is <see langword="true"/> if the file type is to be shown on the games list, <see langword="false"/> otherwise.</returns> /// <returns>The current value of the setting. Value is <see langword="true"/> if the file type is the be shown on the games list, <see langword="false"/> otherwise.</returns>
public static bool GetConfigValue(this FileTypes type, ShownFileTypeSettings config) => type switch public static bool GetConfigValue(this FileTypes type, ShownFileTypeSettings config) => type switch
{ {
FileTypes.NSP => config.NSP.Value, FileTypes.NSP => config.NSP.Value,
@@ -0,0 +1,64 @@
using LibHac.Common;
using LibHac.Ncm;
using LibHac.Ns;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.HLE;
using Ryujinx.HLE.FileSystem;
using Ryujinx.UI.App.Common;
namespace Ryujinx.UI.Common.Helper
{
public readonly struct AppletMetadata
{
private readonly ContentManager _contentManager;
public string Name { get; }
public ulong ProgramId { get; }
public string Version { get; }
public AppletMetadata(ContentManager contentManager, string name, ulong programId, string version = "1.0.0")
: this(name, programId, version)
{
_contentManager = contentManager;
}
public AppletMetadata(string name, ulong programId, string version = "1.0.0")
{
Name = name;
ProgramId = programId;
Version = version;
}
public string GetContentPath(ContentManager contentManager)
=> (contentManager ?? _contentManager)
.GetInstalledContentPath(ProgramId, StorageId.BuiltInSystem, NcaContentType.Program);
public bool CanStart(ContentManager contentManager, out ApplicationData appData, out BlitStruct<ApplicationControlProperty> appControl)
{
contentManager ??= _contentManager;
if (contentManager == null)
{
appData = null;
appControl = new BlitStruct<ApplicationControlProperty>(0);
return false;
}
appData = new()
{
Name = Name,
Id = ProgramId,
Path = GetContentPath(contentManager)
};
if (string.IsNullOrEmpty(appData.Path))
{
appControl = new BlitStruct<ApplicationControlProperty>(0);
return false;
}
appControl = StructHelpers.CreateCustomNacpData(Name, Version);
return true;
}
}
}
@@ -1,7 +1,7 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using System.Collections.Generic; using System.Collections.Generic;
namespace Ryujinx.Ava.Utilities namespace Ryujinx.UI.Common.Helper
{ {
public static class CommandLineState public static class CommandLineState
{ {
@@ -3,7 +3,7 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
namespace Ryujinx.Common.Helper namespace Ryujinx.UI.Common.Helper
{ {
public static partial class ConsoleHelper public static partial class ConsoleHelper
{ {
@@ -3,18 +3,18 @@ using LibHac.Fs;
using LibHac.Fs.Fsa; using LibHac.Fs.Fsa;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.Utilities; using Ryujinx.HLE.Utilities;
using Ryujinx.UI.Common.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Path = System.IO.Path; using Path = System.IO.Path;
namespace Ryujinx.Ava.Utilities namespace Ryujinx.UI.Common.Helper
{ {
public static class DownloadableContentsHelper public static class DownloadableContentsHelper
{ {
@@ -8,7 +8,7 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
namespace Ryujinx.Common.Helper namespace Ryujinx.UI.Common.Helper
{ {
public static partial class FileAssociationHelper public static partial class FileAssociationHelper
{ {
@@ -3,7 +3,7 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.Versioning; using System.Runtime.Versioning;
namespace Ryujinx.Common.Helper namespace Ryujinx.UI.Common.Helper
{ {
[SupportedOSPlatform("linux")] [SupportedOSPlatform("linux")]
public static class LinuxHelper public static class LinuxHelper
@@ -2,7 +2,7 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
namespace Ryujinx.Common.Helper namespace Ryujinx.UI.Common.Helper
{ {
[SupportedOSPlatform("macos")] [SupportedOSPlatform("macos")]
public static partial class ObjectiveC public static partial class ObjectiveC
@@ -5,7 +5,7 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Ryujinx.Common.Helper namespace Ryujinx.UI.Common.Helper
{ {
public static partial class OpenHelper public static partial class OpenHelper
{ {
@@ -1,10 +1,9 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.UI;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using System; using System;
using System.IO; using System.IO;
namespace Ryujinx.Ava.Utilities namespace Ryujinx.UI.Common.Helper
{ {
/// <summary> /// <summary>
/// Ensure installation validity /// Ensure installation validity
@@ -7,7 +7,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Runtime.Versioning; using System.Runtime.Versioning;
namespace Ryujinx.Ava.Utilities namespace Ryujinx.UI.Common.Helper
{ {
public static class ShortcutHelper public static class ShortcutHelper
{ {
@@ -31,7 +31,7 @@ namespace Ryujinx.Ava.Utilities
private static void CreateShortcutLinux(string applicationFilePath, string applicationId, byte[] iconData, string iconPath, string desktopPath, string cleanedAppName) private static void CreateShortcutLinux(string applicationFilePath, string applicationId, byte[] iconData, string iconPath, string desktopPath, string cleanedAppName)
{ {
string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx.sh"); string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx.sh");
var desktopFile = EmbeddedResources.ReadAllText("Ryujinx/Assets/ShortcutFiles/shortcut-template.desktop"); var desktopFile = EmbeddedResources.ReadAllText("Ryujinx.UI.Common/shortcut-template.desktop");
iconPath += ".png"; iconPath += ".png";
var image = SKBitmap.Decode(iconData); var image = SKBitmap.Decode(iconData);
@@ -47,8 +47,8 @@ namespace Ryujinx.Ava.Utilities
private static void CreateShortcutMacos(string appFilePath, string applicationId, byte[] iconData, string desktopPath, string cleanedAppName) private static void CreateShortcutMacos(string appFilePath, string applicationId, byte[] iconData, string desktopPath, string cleanedAppName)
{ {
string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx"); string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx");
var plistFile = EmbeddedResources.ReadAllText("Ryujinx/Assets/ShortcutFiles/shortcut-template.plist"); var plistFile = EmbeddedResources.ReadAllText("Ryujinx.UI.Common/shortcut-template.plist");
var shortcutScript = EmbeddedResources.ReadAllText("Ryujinx/Assets/ShortcutFiles/shortcut-launch-script.sh"); var shortcutScript = EmbeddedResources.ReadAllText("Ryujinx.UI.Common/shortcut-launch-script.sh");
// Macos .App folder // Macos .App folder
string contentFolderPath = Path.Combine("/Applications", cleanedAppName + ".app", "Contents"); string contentFolderPath = Path.Combine("/Applications", cleanedAppName + ".app", "Contents");
string scriptFolderPath = Path.Combine(contentFolderPath, "MacOS"); string scriptFolderPath = Path.Combine(contentFolderPath, "MacOS");
@@ -1,6 +1,7 @@
using Ryujinx.HLE.Loaders.Processes; using Ryujinx.HLE.Loaders.Processes;
using System;
namespace Ryujinx.Ava.Utilities namespace Ryujinx.UI.Common.Helper
{ {
public static class TitleHelper public static class TitleHelper
{ {
@@ -6,14 +6,14 @@ using LibHac.Ncm;
using LibHac.Ns; using LibHac.Ns;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.HLE.Loaders.Processes.Extensions;
using Ryujinx.HLE.Utilities; using Ryujinx.HLE.Utilities;
using Ryujinx.UI.Common.Configuration;
using Ryujinx.UI.Common.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -22,7 +22,7 @@ using Path = System.IO.Path;
using SpanHelpers = LibHac.Common.SpanHelpers; using SpanHelpers = LibHac.Common.SpanHelpers;
using TitleUpdateMetadata = Ryujinx.Common.Configuration.TitleUpdateMetadata; using TitleUpdateMetadata = Ryujinx.Common.Configuration.TitleUpdateMetadata;
namespace Ryujinx.Ava.Utilities namespace Ryujinx.UI.Common.Helper
{ {
public static class TitleUpdatesHelper public static class TitleUpdatesHelper
{ {
@@ -1,9 +1,8 @@
using Ryujinx.Ava.Common.Locale;
using System; using System;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
namespace Ryujinx.Ava.Utilities namespace Ryujinx.UI.Common.Helper
{ {
public static class ValueFormatUtils public static class ValueFormatUtils
{ {
@@ -76,7 +75,7 @@ namespace Ryujinx.Ava.Utilities
{ {
culture ??= CultureInfo.CurrentCulture; culture ??= CultureInfo.CurrentCulture;
return utcDateTime?.ToLocalTime().ToString(culture) ?? LocaleManager.Instance[LocaleKeys.Never]; return utcDateTime?.ToLocalTime().ToString(culture);
} }
/// <summary> /// <summary>
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Common.Models.Amiibo namespace Ryujinx.UI.Common.Models.Amiibo
{ {
public struct AmiiboApi : IEquatable<AmiiboApi> public struct AmiiboApi : IEquatable<AmiiboApi>
{ {
@@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Common.Models.Amiibo namespace Ryujinx.UI.Common.Models.Amiibo
{ {
public class AmiiboApiGamesSwitch public class AmiiboApiGamesSwitch
{ {
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Common.Models.Amiibo namespace Ryujinx.UI.Common.Models.Amiibo
{ {
public class AmiiboApiUsage public class AmiiboApiUsage
{ {
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Common.Models.Amiibo namespace Ryujinx.UI.Common.Models.Amiibo
{ {
public struct AmiiboJson public struct AmiiboJson
{ {
@@ -1,7 +1,9 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Common.Models.Amiibo namespace Ryujinx.UI.Common.Models.Amiibo
{ {
[JsonSerializable(typeof(AmiiboJson))] [JsonSerializable(typeof(AmiiboJson))]
public partial class AmiiboJsonSerializerContext : JsonSerializerContext; public partial class AmiiboJsonSerializerContext : JsonSerializerContext
{
}
} }
@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Common.Models namespace Ryujinx.UI.Common.Models
{ {
// NOTE: most consuming code relies on this model being value-comparable // NOTE: most consuming code relies on this model being value-comparable
public record DownloadableContentModel(ulong TitleId, string ContainerPath, string FullPath) public record DownloadableContentModel(ulong TitleId, string ContainerPath, string FullPath)
@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Common.Models.Github namespace Ryujinx.UI.Common.Models.Github
{ {
public class GithubReleaseAssetJsonResponse public class GithubReleaseAssetJsonResponse
{ {
@@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Ryujinx.Ava.Common.Models.Github namespace Ryujinx.UI.Common.Models.Github
{ {
public class GithubReleasesJsonResponse public class GithubReleasesJsonResponse
{ {
@@ -1,7 +1,9 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Common.Models.Github namespace Ryujinx.UI.Common.Models.Github
{ {
[JsonSerializable(typeof(GithubReleasesJsonResponse), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(GithubReleasesJsonResponse), GenerationMode = JsonSourceGenerationMode.Metadata)]
public partial class GithubReleasesJsonSerializerContext : JsonSerializerContext; public partial class GithubReleasesJsonSerializerContext : JsonSerializerContext
{
}
} }
@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Common.Models namespace Ryujinx.UI.Common.Models
{ {
// NOTE: most consuming code relies on this model being value-comparable // NOTE: most consuming code relies on this model being value-comparable
public record TitleUpdateModel(ulong TitleId, ulong Version, string DisplayVersion, string Path) public record TitleUpdateModel(ulong TitleId, ulong Version, string DisplayVersion, string Path)
@@ -1,8 +1,8 @@
using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.UI.App.Common;
namespace Ryujinx.Ava.Common.Models namespace Ryujinx.UI.Common.Models
{ {
public record XCITrimmerFileModel( public record XCITrimmerFileModel(
string Name, string Name,
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 68 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 81 KiB

@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1050 1050.5"
style="enable-background:new 0 0 1050 1050.5;" xml:space="preserve">
<style type="text/css">
.st0{fill:#20221F;}
.st1{fill:#3B3B3B;}
.st2{fill:#121212;}
.st3{fill:#444542;}
.st4{fill:#FFFFFF;}
.st5{fill:#444542;stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;}
.st6{fill:#454644;}
.st7{fill:#454644;stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;}
.st8{fill:#3B3C3A;}
.st9{font-family:'Helvetica-Bold';}
.st10{font-size:40px;}
.st11{fill:#0D0D0A;}
</style>
<g id="Front">
<path id="Right_Grip_00000028282943321285403220000008369785803052272051_" class="st0" d="M766,850.5
c34,28.2,27.6,35.9,68.5,108.5c36.7,74.7,64.4,104.4,125.1,84.1v0c95.3-57.9,59.3-145.3,43.6-275.2c-10-60.6-35.6-190.3-35.6-190.3
L766,850.5z"/>
<path id="Left_Grip" class="st0" d="M82.3,577.6c0,0-25.6,129.7-35.6,190.3C31,897.8-5,985.1,90.3,1043v0
c60.8,20.3,88.4-9.4,125.1-84.1c40.9-72.7,34.5-80.3,68.5-108.5L82.3,577.6z"/>
<path id="Right_Bumper_00000006710349871522532470000011078040965381267594_" class="st1" d="M676.3,378.4
c10.1-4.3,39.7-22.5,58.7-19.7c59.5,0.9,166.7,17.7,172.6,81.2"/>
<path id="Left_Bumper_00000024680414077879639570000011759596763560342154_" class="st1" d="M142.4,439.9
c5.9-63.4,113-80.2,172.6-81.2c19-2.8,48.6,15.4,58.7,19.7"/>
<path id="Background_00000141418846164053065470000016150094984198570163_" class="st2" d="M766,850.5
c35.5-30.8,68.5-74.7,96-113.5c26.9-36.3,94.7-136.7,105.6-159.3c0-2.4-6.3-30.1-12.8-56.2C919.1,361.9,702.2,378.1,525,378.1
c-177.4,0-394.1-16.2-429.9,143.3c-6.5,26-12.8,53.8-12.8,56.2c10.9,22.6,78.8,123,105.6,159.3c27.5,38.8,60.5,82.8,96,113.5"/>
<g id="Directional_Pad">
<path id="Background_00000032628022449190479560000015279211462520783249_" class="st3" d="M466.2,683.5h-40c-2.8,0-5-2.2-5-5v-40
c0-2.8-2.2-5-5-5h-30c-2.8,0-5,2.2-5,5v40c0,2.8-2.2,5-5,5h-40c-2.8,0-5,2.2-5,5v30c0,2.8,2.2,5,5,5h40c2.8,0,5,2.2,5,5v40
c0,2.8,2.2,5,5,5h30c2.8,0,5-2.2,5-5v-40c0-2.8,2.2-5,5-5h40c2.8,0,5-2.2,5-5v-30C471.2,685.8,469,683.5,466.2,683.5z"/>
<g id="Arrows">
<g>
<polygon class="st4" points="393.7,746 408.7,746 401.2,761 "/>
</g>
<g>
<polygon class="st4" points="358.7,696 358.7,711 343.7,703.5 "/>
</g>
<g>
<polygon class="st4" points="408.7,661 393.7,661 401.2,646 "/>
</g>
<g>
<polygon class="st4" points="443.7,711 443.7,696 458.7,703.5 "/>
</g>
</g>
</g>
<g id="R_Thumbstick_00000152226188525111835500000011838297421350334865_">
<circle id="Background_00000035532849542660068350000006517224202948159422_" class="st0" cx="650.6" cy="703.5" r="55"/>
<circle id="Stick" class="st5" cx="650.6" cy="703.5" r="45"/>
</g>
<g id="L_Thumbstick_00000047032468231999382210000005512347386782594484_">
<circle id="Background_00000182502673988292164000000007125719133096369561_" class="st0" cx="240.2" cy="564.8" r="55"/>
<circle id="Stick_00000075121990265259598900000000214370239054002365_" class="st5" cx="240.2" cy="564.8" r="45"/>
</g>
<g id="Minus_Button">
<circle id="_Background_00000120554951013892796430000015877571645746699662_" class="st6" cx="401" cy="489.3" r="22.5"/>
<polyline id="Plus_00000039131319101621183460000006196023733899658629_" class="st4" points="386.2,491.8 386.2,486.8
416.2,486.8 416.2,491.8 "/>
</g>
<g id="Plus_Button">
<circle id="_Background" class="st6" cx="650.4" cy="489.6" r="22.5"/>
<polygon id="Plus" class="st4" points="665.6,487.1 653.1,487.1 653.1,474.4 648.1,474.4 648.1,487.1 635.6,487.1 635.6,492.1
648.1,492.1 648.1,504.4 653.1,504.4 653.1,492.1 665.6,492.1 "/>
</g>
<g id="Home_Button_00000029758737660217614780000001403165237001195407_">
<circle id="_Background_00000132788487854287834010000009548421243227981499_" class="st6" cx="605.4" cy="564.8" r="22.5"/>
<path id="Home" class="st4" d="M605.4,549.8l-15,15h5v15h20v-15h5L605.4,549.8z M610.4,574.8h-10v-10h10V574.8z"/>
</g>
<g id="Capture_Button_00000105394663133565750060000017455731898661404072_">
<path class="st6" d="M468.6,586.5h-30c-2.8,0-5-2.2-5-5v-29.5c0-2.8,2.2-5,5-5h30c2.8,0,5,2.2,5,5v29.5
C473.6,584.2,471.4,586.5,468.6,586.5z"/>
<circle class="st7" cx="453.6" cy="566.7" r="15"/>
</g>
<g id="Buttons_00000023239109225132251950000005218343074279628213_">
<g id="A_Button">
<circle id="Background_00000006699118933065716380000004636085088820886913_" class="st8" cx="863.9" cy="564.8" r="35"/>
<text transform="matrix(1 0 0 1 849.4224 578.6607)" class="st4 st9 st10">A</text>
</g>
<g id="X_Button">
<circle id="Background_00000083074713085756701790000016893839312974798515_" class="st8" cx="793.9" cy="494.8" r="35"/>
<text transform="matrix(1 0 0 1 780.5266 508.6604)" class="st4 st9 st10">X</text>
</g>
<g id="Y_Button_00000100344340438574137780000014238704828967683973_">
<circle id="Background_00000137100455694543496620000011124722786613194377_" class="st8" cx="723.9" cy="564.8" r="35"/>
<text transform="matrix(1 0 0 1 710.5263 578.661)" class="st4 st9 st10">Y</text>
</g>
<g id="B_Button_00000041994261956088037220000013468634544777304733_">
<circle id="Background_00000096038108578846046800000001873940014252420514_" class="st8" cx="793.9" cy="634.8" r="35"/>
<text transform="matrix(1 0 0 1 780.9706 648.6605)" class="st4 st9 st10">B</text>
</g>
</g>
</g>
<g id="Top_Down">
<path id="Left_Grip_00000026131988385328425370000016677941743356253314_" class="st0" d="M219.2,78.5
c-12.5-17.6-25.9-42.3-45.6-58.6C153.5,3.3,112.1-4.7,87.1,5.8c-13.9,5.8-33.4,33.1-42.7,52.8C33.9,80.9,30.4,109.9,32,141.4
c1.2,25.1,5.3,51.7,14.2,78.6c0,0,14.3,53.8,42.8,80.8c11.2,10.6,35,26.6,35,26.6l116-217.5C240,109.9,224.6,86.2,219.2,78.5z"/>
<path id="Right_Grip_00000016782759094708820330000002450847065936193693_" class="st0" d="M828.6,78.5
c12.5-17.6,25.9-42.3,45.6-58.6c20.1-16.6,61.4-24.5,86.5-14.1c13.9,5.8,33.4,33.1,42.7,52.8c10.5,22.3,13.9,51.3,12.4,82.8
c-1.2,25.1-5.3,51.7-14.2,78.6c0,0-14.3,53.8-42.8,80.8c-11.2,10.6-35,26.6-35,26.6l-116-217.5C807.8,109.9,823.2,86.2,828.6,78.5z
"/>
<path id="Background_00000169534857628063347190000007586592143875928969_" class="st11" d="M866,122.2
c66.3,18.7,85.1,128.8,69,186c-2.5,54.2-148.9,15.3-265.1,31.2c-41.1,1.7-91.8,2.4-145.9,2.3c-54.1,0-104.8-0.6-145.9-2.3
c-116.2-15.9-262.6,23.1-265.1-31.2c-16.1-57.1,2.6-167.3,69-186l60.5-18.8l38.9-1.9c40.2,0.1,142.8,0,242.7,0
c99.9,0,202.4,0.1,242.7,0l38.9,1.9L866,122.2z"/>
<g id="ZL_Trigger_00000005254517714433203260000014117442438696169895_">
<path id="Background_00000111870097528015387240000017384507710402295183_" class="st1" d="M145.9,239.2
c15.2-97.4,38.1-147.2,141.7-137c8.2,16.4,43.3,83,50.6,105.7C280.6,227.2,204.7,225.6,145.9,239.2z"/>
<text id="ZL_Trigger" transform="matrix(1.0139 0 0 1 218.3906 179.3992)" class="st4 st9 st10">ZL</text>
</g>
<g id="ZR_Trigger">
<path id="Background_00000133526766189752063450000016781240006605114763_" class="st1" d="M716.2,207.9
c7.4-22.7,42.5-89.3,50.6-105.7c103.7-10.2,126.5,39.6,141.7,137C849.8,225.6,773.8,227.2,716.2,207.9z"/>
<text id="ZL_Trigger_00000000206350378518266660000001315160307759857328_" transform="matrix(1.0139 0 0 1 784.2356 179.3992)" class="st4 st9 st10">ZR</text>
</g>
<g id="R_Trigger_00000085939413106284991650000014018840000393673094_">
<path id="Background" class="st1" d="M664,318.5c7-10.1,27.8-78.4,45.4-78.7C1040.8,243.7,897.1,334,664,318.5z"/>
<text id="R_Trigger" transform="matrix(1 0 0 1 769.6461 292.8947)" class="st4 st9 st10">R</text>
</g>
<g id="L_Trigger">
<path id="Background_00000043427985111927735300000011910735497762731703_" class="st1" d="M340.6,238.6
c17.6,0.3,38.4,68.6,45.4,78.7C152.9,332.8,9.2,242.6,340.6,238.6z"/>
<text id="R_Trigger_00000092444210070373642420000009814634285137007748_" transform="matrix(1 0 0 1 253.7327 291.7279)" class="st4 st9 st10">L</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.0 KiB

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Before

Width:  |  Height:  |  Size: 253 KiB

After

Width:  |  Height:  |  Size: 253 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@@ -21,6 +21,34 @@
<None Remove="Resources\Logo_Ryujinx.png" /> <None Remove="Resources\Logo_Ryujinx.png" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Controller_JoyConLeft.svg" />
<EmbeddedResource Include="Resources\Controller_JoyConPair.svg" />
<EmbeddedResource Include="Resources\Controller_JoyConRight.svg" />
<EmbeddedResource Include="Resources\Controller_ProCon.svg" />
<EmbeddedResource Include="Resources\Icon_NCA.png" />
<EmbeddedResource Include="Resources\Icon_NRO.png" />
<EmbeddedResource Include="Resources\Icon_NSO.png" />
<EmbeddedResource Include="Resources\Icon_NSP.png" />
<EmbeddedResource Include="Resources\Icon_XCI.png" />
<EmbeddedResource Include="Resources\Logo_Amiibo.png" />
<EmbeddedResource Include="Resources\Logo_Ryujinx.png" />
<EmbeddedResource Include="Resources\Logo_Ryujinx_AntiAlias.png" />
<EmbeddedResource Include="Resources\Logo_Discord_Dark.png" />
<EmbeddedResource Include="Resources\Logo_Discord_Light.png" />
<EmbeddedResource Include="Resources\Logo_GitHub_Dark.png" />
<EmbeddedResource Include="Resources\Logo_GitHub_Light.png" />
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64' OR '$(RuntimeIdentifier)' == ''">
<EmbeddedResource Include="..\..\distribution\linux\shortcut-template.desktop" />
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64' OR '$(RuntimeIdentifier)' == ''">
<EmbeddedResource Include="..\..\distribution\macos\shortcut-template.plist" />
<EmbeddedResource Include="..\..\distribution\macos\shortcut-launch-script.sh" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DiscordRichPresence" /> <PackageReference Include="DiscordRichPresence" />
<PackageReference Include="DynamicData" /> <PackageReference Include="DynamicData" />
@@ -5,7 +5,7 @@ using System.Globalization;
using System.IO; using System.IO;
using System.Runtime.Versioning; using System.Runtime.Versioning;
namespace Ryujinx.Ava.Utilities.SystemInfo namespace Ryujinx.UI.Common.SystemInfo
{ {
[SupportedOSPlatform("linux")] [SupportedOSPlatform("linux")]
class LinuxSystemInfo : SystemInfo class LinuxSystemInfo : SystemInfo
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using System.Text; using System.Text;
namespace Ryujinx.Ava.Utilities.SystemInfo namespace Ryujinx.UI.Common.SystemInfo
{ {
[SupportedOSPlatform("macos")] [SupportedOSPlatform("macos")]
partial class MacOSSystemInfo : SystemInfo partial class MacOSSystemInfo : SystemInfo
@@ -1,10 +1,11 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.UI.Common.Helper;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics.X86;
using System.Text; using System.Text;
namespace Ryujinx.Ava.Utilities.SystemInfo namespace Ryujinx.UI.Common.SystemInfo
{ {
public class SystemInfo public class SystemInfo
{ {
@@ -4,7 +4,7 @@ using System.Management;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
namespace Ryujinx.Ava.Utilities.SystemInfo namespace Ryujinx.UI.Common.SystemInfo
{ {
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]
partial class WindowsSystemInfo : SystemInfo partial class WindowsSystemInfo : SystemInfo
@@ -1,4 +1,4 @@
namespace Ryujinx.Common.UI namespace Ryujinx.UI.Common
{ {
/// <summary> /// <summary>
/// Represent a common error that could be reported to the user by the emulator. /// Represent a common error that could be reported to the user by the emulator.

Some files were not shown because too many files have changed in this diff Show More