mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-06-16 09:19:14 +00:00
Compare commits
4 Commits
Canary-1.3
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d67a86efd | ||
|
|
e777e3f93b | ||
|
|
7b19e041cb | ||
|
|
e7a3c94b9c |
@@ -63,6 +63,6 @@
|
||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.9" />
|
||||
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
||||
<PackageVersion Include="System.IO.Hashing" Version="9.0.15" />
|
||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.1.3" />
|
||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.1.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -47,12 +47,14 @@ def get_new_name(
|
||||
input_component = str(input_dylib_path).replace(str(input_directory), "")[1:]
|
||||
return Path(os.path.join(output_directory, input_component))
|
||||
|
||||
def get_archs(dylib_path: Path) -> list[str]:
|
||||
res = subprocess.check_output([LIPO, "-info", str(dylib_path)]).decode("utf-8")
|
||||
if res.startswith("Non-fat file"):
|
||||
return [res.split(":")[-1].strip()]
|
||||
else:
|
||||
return res.split("are:")[-1].strip().split()
|
||||
|
||||
def is_fat_file(dylib_path: Path) -> str:
|
||||
res = subprocess.check_output([LIPO, "-info", str(dylib_path.absolute())]).decode(
|
||||
"utf-8"
|
||||
)
|
||||
|
||||
return not res.split("\n")[0].startswith("Non-fat file")
|
||||
|
||||
|
||||
def construct_universal_dylib(
|
||||
arm64_input_dylib_path: Path, x86_64_input_dylib_path: Path, output_dylib_path: Path
|
||||
@@ -67,12 +69,11 @@ def construct_universal_dylib(
|
||||
os.path.basename(arm64_input_dylib_path.resolve()), output_dylib_path
|
||||
)
|
||||
else:
|
||||
arm64_archs = get_archs(arm64_input_dylib_path)
|
||||
x86_64_archs = get_archs(x86_64_input_dylib_path) if x86_64_input_dylib_path.exists() else []
|
||||
|
||||
if "arm64" in arm64_archs and "x86_64" in arm64_archs:
|
||||
shutil.copy2(arm64_input_dylib_path, output_dylib_path)
|
||||
elif x86_64_archs:
|
||||
if is_fat_file(arm64_input_dylib_path) or not x86_64_input_dylib_path.exists():
|
||||
with open(output_dylib_path, "wb") as dst:
|
||||
with open(arm64_input_dylib_path, "rb") as src:
|
||||
dst.write(src.read())
|
||||
else:
|
||||
subprocess.check_call(
|
||||
[
|
||||
LIPO,
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Ryujinx.Cpu.Signal
|
||||
public SignalHandlerRangeArray Ranges;
|
||||
}
|
||||
|
||||
static class NativeSignalHandler
|
||||
public static class NativeSignalHandler
|
||||
{
|
||||
private static readonly nint _handlerConfig;
|
||||
private static nint _signalHandlerPtr;
|
||||
|
||||
@@ -16,15 +16,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
DescriptorSetLayout[] layouts = new DescriptorSetLayout[setDescriptors.Count];
|
||||
bool[] updateAfterBindFlags = new bool[setDescriptors.Count];
|
||||
|
||||
|
||||
bool isMoltenVk = gd.IsMoltenVk;
|
||||
|
||||
|
||||
for (int setIndex = 0; setIndex < setDescriptors.Count; setIndex++)
|
||||
{
|
||||
ResourceDescriptorCollection rdc = setDescriptors[setIndex];
|
||||
|
||||
ResourceStages activeStages = ResourceStages.None;
|
||||
|
||||
|
||||
if (isMoltenVk)
|
||||
{
|
||||
for (int descIndex = 0; descIndex < rdc.Descriptors.Count; descIndex++)
|
||||
@@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// causes invalid resource errors, allow the binding on all active stages as workaround.
|
||||
// https://github.com/KhronosGroup/MoltenVK/issues/1870
|
||||
stages = activeStages;
|
||||
}
|
||||
}
|
||||
|
||||
layoutBindings[descIndex] = new DescriptorSetLayoutBinding
|
||||
{
|
||||
|
||||
@@ -439,7 +439,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
features2.Features.MultiViewport && !(IsMoltenVk && Vendor == Vendor.Amd), // Workaround for AMD on MoltenVK issue
|
||||
featuresRobustness2.NullDescriptor || IsMoltenVk,
|
||||
supportsPushDescriptors,
|
||||
IsMoltenVk ? 16 : propertiesPushDescriptor.MaxPushDescriptors, // In case an old version of MoltenVK is used, apply a limit to prevent vertex explosions.
|
||||
IsMoltenVk ? 16 : propertiesPushDescriptor.MaxPushDescriptors, // Prevents vertex explosions on MoltenVK.
|
||||
featuresPrimitiveTopologyListRestart.PrimitiveTopologyListRestart,
|
||||
featuresPrimitiveTopologyListRestart.PrimitiveTopologyPatchListRestart,
|
||||
supportsTransformFeedback,
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnicornEngine.Const;
|
||||
|
||||
namespace Ryujinx.Tests.Unicorn
|
||||
{
|
||||
public class UnicornAArch32 : IDisposable
|
||||
{
|
||||
struct UcArmCpReg
|
||||
{
|
||||
public uint Cp;
|
||||
public uint Is64;
|
||||
public uint Sec;
|
||||
public uint CRn;
|
||||
public uint CRm;
|
||||
public uint Opc1;
|
||||
public uint Opc2;
|
||||
public uint Val;
|
||||
}
|
||||
|
||||
internal readonly UnicornEngine.Unicorn Uc;
|
||||
private bool _isDisposed;
|
||||
|
||||
@@ -38,7 +51,7 @@ namespace Ryujinx.Tests.Unicorn
|
||||
|
||||
public int Fpscr
|
||||
{
|
||||
get => (int)GetRegister(Arm.UC_ARM_REG_FPSCR) | ((int)GetRegister(Arm.UC_ARM_REG_FPSCR_NZCV));
|
||||
get => (int)GetRegister(Arm.UC_ARM_REG_FPSCR);
|
||||
set => SetRegister(Arm.UC_ARM_REG_FPSCR, (uint)value);
|
||||
}
|
||||
|
||||
@@ -85,8 +98,22 @@ namespace Ryujinx.Tests.Unicorn
|
||||
public UnicornAArch32()
|
||||
{
|
||||
Uc = new UnicornEngine.Unicorn(Common.UC_ARCH_ARM, Common.UC_MODE_LITTLE_ENDIAN);
|
||||
|
||||
SetRegister(Arm.UC_ARM_REG_C1_C0_2, GetRegister(Arm.UC_ARM_REG_C1_C0_2) | 0xf00000);
|
||||
|
||||
UcArmCpReg reg = new()
|
||||
{
|
||||
Cp = 15,
|
||||
Is64 = 0,
|
||||
Sec = 0,
|
||||
CRn = 13,
|
||||
Opc1 = 0,
|
||||
CRm = 0,
|
||||
Opc2 = 2
|
||||
};
|
||||
|
||||
GetRegister(Arm.UC_ARM_REG_CP_REG, ref reg);
|
||||
reg.Val |= 0xf00000;
|
||||
SetRegister(Arm.UC_ARM_REG_CP_REG, reg);
|
||||
|
||||
SetRegister(Arm.UC_ARM_REG_FPEXC, 0x40000000);
|
||||
}
|
||||
|
||||
@@ -204,6 +231,17 @@ namespace Ryujinx.Tests.Unicorn
|
||||
SetVector(Arm.UC_ARM_REG_D0 + index * 2, value);
|
||||
}
|
||||
|
||||
public void GetRegister<T>(int register, ref T obj) where T : unmanaged
|
||||
{
|
||||
Span<T> span = new(ref obj);
|
||||
Span<byte> dataSpan = MemoryMarshal.Cast<T, byte>(span);
|
||||
byte[] data = dataSpan.ToArray();
|
||||
|
||||
Uc.RegRead(register, data);
|
||||
|
||||
data.AsSpan().CopyTo(dataSpan);
|
||||
}
|
||||
|
||||
public uint GetRegister(int register)
|
||||
{
|
||||
byte[] data = new byte[4];
|
||||
@@ -213,6 +251,13 @@ namespace Ryujinx.Tests.Unicorn
|
||||
return BitConverter.ToUInt32(data, 0);
|
||||
}
|
||||
|
||||
public void SetRegister<T>(int register, T obj) where T : unmanaged
|
||||
{
|
||||
byte[] data = MemoryMarshal.Cast<T, byte>(new Span<T>(ref obj)).ToArray();
|
||||
|
||||
Uc.RegWrite(register, data);
|
||||
}
|
||||
|
||||
public void SetRegister(int register, uint value)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(value);
|
||||
|
||||
@@ -7,6 +7,7 @@ using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory.PartialUnmaps;
|
||||
using Ryujinx.Cpu;
|
||||
using Ryujinx.Cpu.Jit;
|
||||
using Ryujinx.Cpu.Signal;
|
||||
using Ryujinx.Memory;
|
||||
using Ryujinx.Memory.Tracking;
|
||||
using System;
|
||||
@@ -60,6 +61,8 @@ namespace Ryujinx.Tests.Memory
|
||||
new JitMemoryAllocator(),
|
||||
new MockMemoryManager(),
|
||||
AddressTable<ulong>.CreateForArm(true, MemoryManagerType.SoftwarePageTable));
|
||||
|
||||
NativeSignalHandler.InitializeSignalHandler();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
<PublishTrimmed>true</PublishTrimmed>
|
||||
<TrimMode>partial</TrimMode>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<!--
|
||||
FluentAvalonia, used in the Avalonia UI, requires a workaround for the json serializer used internally when using .NET 8+ System.Text.Json.
|
||||
See:
|
||||
https://github.com/amwx/FluentAvalonia/issues/481
|
||||
https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-8/
|
||||
-->
|
||||
|
||||
|
||||
<PropertyGroup>
|
||||
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
|
||||
</PropertyGroup>
|
||||
@@ -73,7 +73,7 @@
|
||||
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
|
||||
<PackageReference Include="SPB" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.RenderDocApi\Ryujinx.Graphics.RenderDocApi.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj" />
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Ryujinx.Ava.Systems
|
||||
LargeImageText = TruncateToByteLength(_description)
|
||||
},
|
||||
Details = "Main Menu",
|
||||
State = "Idling",
|
||||
State = "Waiting",
|
||||
Timestamps = EmulatorStartedAt
|
||||
};
|
||||
|
||||
|
||||
@@ -1069,7 +1069,6 @@ namespace Ryujinx.Ava.Systems.PlayReport
|
||||
|
||||
_ => FormattedValue.ForceReset
|
||||
};
|
||||
|
||||
private static FormattedValue TomodachiLifeLTD_Status(SingleValue value)
|
||||
{
|
||||
MessagePackObject messagePackObject = value.Matched.PackedValue;
|
||||
@@ -1077,8 +1076,9 @@ namespace Ryujinx.Ava.Systems.PlayReport
|
||||
|
||||
int miiCount = messagePackObjectDictionary["MiiNum"].AsInt32();
|
||||
int fountainLevel = messagePackObjectDictionary["FountainLevel"].AsInt32();
|
||||
|
||||
return $"Looking after {"Mii".ToQuantity(miiCount)}, with an island level of {fountainLevel}";
|
||||
|
||||
// Fountain Level should be kept consistent throughout code, so I basically made sure of it
|
||||
return $"Looking after {"Mii".ToQuantity(miiCount)}, with a fountain level of {fountainLevel}";
|
||||
}
|
||||
|
||||
private static FormattedValue AnimalCrossingNewHorizons_AppCommon(SingleValue value)
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static Ryujinx.Ava.Utilities.StorageProviderExtensions;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
@@ -128,7 +129,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public async void Add()
|
||||
{
|
||||
IReadOnlyList<IStorageFile> result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
IReadOnlyList<IStorageFile> result = await CoreDumpable(() => _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.SelectDlcDialogTitle],
|
||||
AllowMultiple = true,
|
||||
@@ -141,7 +142,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
MimeTypes = ["application/x-nx-nsp"],
|
||||
},
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
int totalDlcAdded = 0;
|
||||
foreach (IStorageFile file in result)
|
||||
|
||||
@@ -17,6 +17,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using static Ryujinx.Ava.Utilities.StorageProviderExtensions;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
@@ -288,11 +289,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public async void Add()
|
||||
{
|
||||
IReadOnlyList<IStorageFolder> result = await _storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
IReadOnlyList<IStorageFolder> result = await CoreDumpable(() => _storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.SelectModDialogTitle],
|
||||
AllowMultiple = true,
|
||||
});
|
||||
}));
|
||||
|
||||
foreach (IStorageFolder folder in result)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static Ryujinx.Ava.Utilities.StorageProviderExtensions;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
@@ -148,7 +149,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public async Task Add()
|
||||
{
|
||||
IReadOnlyList<IStorageFile> result = await _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
IReadOnlyList<IStorageFile> result = await CoreDumpable(() => _storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = true,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
@@ -160,7 +161,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
MimeTypes = ["application/x-nx-nsp"],
|
||||
},
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
int totalUpdatesAdded = 0;
|
||||
foreach (IStorageFile file in result)
|
||||
|
||||
@@ -4,10 +4,12 @@ using Avalonia.Platform.Storage;
|
||||
using Avalonia.VisualTree;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Navigation;
|
||||
using Gommon;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Models;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.Utilities;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using SkiaSharp;
|
||||
using System.Collections.Generic;
|
||||
@@ -62,7 +64,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
|
||||
private async void Import_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
IReadOnlyList<IStorageFile> result = await ((Window)this.GetVisualRoot()!).StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
Optional<IStorageFile> result = await ((Window)this.GetVisualRoot()!).StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
@@ -76,9 +78,9 @@ namespace Ryujinx.Ava.UI.Views.User
|
||||
},
|
||||
});
|
||||
|
||||
if (result.Count > 0)
|
||||
if (result.HasValue)
|
||||
{
|
||||
_profile.Image = ProcessProfileImage(File.ReadAllBytes(result[0].Path.LocalPath));
|
||||
_profile.Image = ProcessProfileImage(File.ReadAllBytes(result.Value.Path.LocalPath));
|
||||
_parent.GoBack();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Ryujinx.Ava.Utilities
|
||||
.Then(files => files.Count > 0 ? Optional.Of(files) : default);
|
||||
}
|
||||
|
||||
private static async Task<T> CoreDumpable<T>(Func<Task<T>> picker)
|
||||
public static async Task<T> CoreDumpable<T>(Func<Task<T>> picker)
|
||||
{
|
||||
OsUtils.SetCoreDumpable(true);
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user