Compare commits

...

8 Commits

Author SHA1 Message Date
Ac_K
472119c8da sfdnsres; Fix deserializer of AddrInfoSerialized when addresses are empty (#3924) 2022-11-28 02:53:57 +01:00
Mary-nyan
1865ea87e5 bsd: Fix eventfd broken logic (#3647)
* bsd: Fix eventfd broken logic

This commit fix eventfd logic being broken.

The following changes were made:
- EventFd IPC definition had argument inverted
- EventFd events weren't fired correctly
- Poll logic was wrong and unfinished for eventfd
- Reintroduce workaround from #3385 but in a safer way, and spawn 4
  threads.

* ipc: Rework a bit for multithreads

* Clean up debug logs

* Make server thread yield when managed lock isn't availaible

* Fix replyTargetHandle not being added in the proper locking scope

* Simplify some scopes

* Address gdkchan's comments

* Revert IPC workaround for now

* Reintroduce the EventFileDescriptor workaround
2022-11-27 20:18:05 +00:00
&Olga
18b61aff59 Unbreak bug_report.md (#3915)
* Unbreak bug_report.md

* Update bug_report.md
2022-11-27 20:11:51 +00:00
Luminoso-256
cb22629ac1 HLE: fix small issue in IPsmSession (#3909) 2022-11-27 01:10:42 +00:00
TSRBerry
6f0f99ee2b Avalonia: Fix OpenGL crashing on Linux (#3902)
* ava: Fix OpenGL crashing on Linux

Fixes a regression from #3901

* Fix formatting
2022-11-26 12:06:53 +01:00
TSRBerry
70f2da8fdf ava: Fix invisible vulkan window on Linux (#3901)
Co-authored-by: emmauss <emmausssss@gmail.com>

Co-authored-by: emmauss <emmausssss@gmail.com>
2022-11-25 17:40:44 +00:00
Ac_K
5d3ef7761b ava: Refactor Title Update Manager window (#3898)
* ava: Refactor TitleUpdate Manager window

* Update locale
2022-11-25 17:55:08 +01:00
riperiperi
476b4683cf Fix CB0 alignment with addresses used for 8/16-bit LDG/STG (#3897)
This replacement is meant to be done with the original identified byteOffset, not the one assigned later on by the below conditionals (that already has the constant offset added, for instance).

This fixes videos being pixelated in Xenoblade 3, and other regressions that might have happened since #3847.
2022-11-25 14:39:03 +00:00
18 changed files with 210 additions and 131 deletions

View File

@@ -1,6 +1,6 @@
---
name: Bug Report
about: Something doesn't work correctly in Ryujinx. Note that game-specific issues should be instead posted on the Game Compatibility List at https://github.com/Ryujinx/Ryujinx-Games-List, unless it is a provable regression.
about: Something doesn't work correctly in Ryujinx. Game-specific issues should be posted at https://github.com/Ryujinx/Ryujinx-Games-List instead, unless it is a provable regression.
#assignees:
---

View File

@@ -564,10 +564,10 @@
"Writable": "Writable",
"SelectDlcDialogTitle": "Select DLC files",
"SelectUpdateDialogTitle": "Select update files",
"UserProfileWindowTitle": "Manage User Profiles",
"CheatWindowTitle": "Manage Game Cheats",
"DlcWindowTitle": "Manage Game DLC",
"UpdateWindowTitle": "Manage Game Updates",
"UserProfileWindowTitle": "User Profiles Manager",
"CheatWindowTitle": "Cheats Manager",
"DlcWindowTitle": "Downloadable Content Manager",
"UpdateWindowTitle": "Title Update Manager",
"CheatWindowHeading": "Cheats Available for {0} [{1}]",
"DlcWindowHeading": "{0} Downloadable Content(s) available for {1} ({2})",
"UserProfilesEditProfile": "Edit Selected",
@@ -577,7 +577,7 @@
"UserProfilesSetProfileImage": "Set Profile Image",
"UserProfileEmptyNameError": "Name is required",
"UserProfileNoImageError": "Profile image must be set",
"GameUpdateWindowHeading": "Updates Available for {0} [{1}]",
"GameUpdateWindowHeading": "{0} Update(s) available for {1} ({2})",
"SettingsTabHotkeysResScaleUpHotkey": "Increase resolution:",
"SettingsTabHotkeysResScaleDownHotkey": "Decrease resolution:",
"UserProfilesName": "Name:",

View File

@@ -6,8 +6,8 @@ using SPB.Graphics;
using SPB.Platform;
using SPB.Platform.GLX;
using SPB.Platform.X11;
using SPB.Windowing;
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
@@ -15,12 +15,12 @@ using static Ryujinx.Ava.Ui.Controls.Win32NativeInterop;
namespace Ryujinx.Ava.Ui.Controls
{
public unsafe class EmbeddedWindow : NativeControlHost
public class EmbeddedWindow : NativeControlHost
{
private WindowProc _wndProcDelegate;
private string _className;
protected GLXWindow X11Window { get; private set; }
protected GLXWindow X11Window { get; set; }
protected IntPtr WindowHandle { get; set; }
protected IntPtr X11Display { get; set; }
@@ -94,19 +94,17 @@ namespace Ryujinx.Ava.Ui.Controls
}
[SupportedOSPlatform("linux")]
IPlatformHandle CreateLinux(IPlatformHandle parent)
protected virtual IPlatformHandle CreateLinux(IPlatformHandle parent)
{
X11Window = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100) as GLXWindow;
X11Window = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100) as GLXWindow;
WindowHandle = X11Window.WindowHandle.RawHandle;
X11Display = X11Window.DisplayHandle.RawHandle;
X11Display = X11Window.DisplayHandle.RawHandle;
return new PlatformHandle(WindowHandle, "X11");
}
[SupportedOSPlatform("windows")]
unsafe IPlatformHandle CreateWin32(IPlatformHandle parent)
IPlatformHandle CreateWin32(IPlatformHandle parent)
{
_className = "NativeWindow-" + Guid.NewGuid();
_wndProcDelegate = WndProc;
@@ -142,7 +140,7 @@ namespace Ryujinx.Ava.Ui.Controls
}
[SupportedOSPlatform("windows")]
internal IntPtr WndProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam)
IntPtr WndProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam)
{
var point = new Point((long)lParam & 0xFFFF, ((long)lParam >> 16) & 0xFFFF);
var root = VisualRoot as Window;

View File

@@ -1,10 +1,13 @@
using Avalonia.Platform;
using Ryujinx.Ava.Ui.Controls;
using Silk.NET.Vulkan;
using SPB.Graphics.Vulkan;
using SPB.Platform.GLX;
using SPB.Platform.Win32;
using SPB.Platform.X11;
using SPB.Windowing;
using System;
using System.Runtime.Versioning;
namespace Ryujinx.Ava.Ui
{
@@ -12,6 +15,18 @@ namespace Ryujinx.Ava.Ui
{
private NativeWindowBase _window;
[SupportedOSPlatform("linux")]
protected override IPlatformHandle CreateLinux(IPlatformHandle parent)
{
X11Window = new GLXWindow(new NativeHandle(X11.DefaultDisplay), new NativeHandle(parent.Handle));
WindowHandle = X11Window.WindowHandle.RawHandle;
X11Display = X11Window.DisplayHandle.RawHandle;
X11Window.Hide();
return new PlatformHandle(WindowHandle, "X11");
}
public SurfaceKHR CreateSurface(Instance instance)
{
if (OperatingSystem.IsWindows())
@@ -20,7 +35,7 @@ namespace Ryujinx.Ava.Ui
}
else if (OperatingSystem.IsLinux())
{
_window = X11Window;
_window = new SimpleX11Window(new NativeHandle(X11Display), new NativeHandle(WindowHandle));
}
else
{

View File

@@ -1283,7 +1283,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
ApplicationData selection = SelectedApplication;
if (selection != null)
{
await new TitleUpdateWindow(_owner.VirtualFileSystem, selection.TitleId, selection.TitleName).ShowDialog(_owner);
await new TitleUpdateWindow(_owner.VirtualFileSystem, ulong.Parse(selection.TitleId, NumberStyles.HexNumber), selection.TitleName).ShowDialog(_owner);
}
}

View File

@@ -8,8 +8,10 @@
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
Width="800"
Height="500"
MinWidth="600"
MinWidth="800"
MinHeight="500"
MaxWidth="800"
MaxHeight="500"
SizeToContent="Height"
WindowStartupLocation="CenterOwner"
mc:Ignorable="d">

View File

@@ -8,7 +8,6 @@ using LibHac.FsSystem;
using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using LibHac.Tools.FsSystem.Save;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Controls;
using Ryujinx.Ava.Ui.Models;
@@ -17,8 +16,6 @@ using Ryujinx.Common.Utilities;
using Ryujinx.HLE.FileSystem;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reactive.Linq;
@@ -36,8 +33,8 @@ namespace Ryujinx.Ava.Ui.Windows
private VirtualFileSystem _virtualFileSystem { get; }
private AvaloniaList<DownloadableContentModel> _downloadableContents { get; set; }
private ulong TitleId { get; }
private string TitleName { get; }
private ulong _titleId { get; }
private string _titleName { get; }
public DownloadableContentManagerWindow()
{
@@ -45,15 +42,16 @@ namespace Ryujinx.Ava.Ui.Windows
InitializeComponent();
Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance["DlcWindowTitle"]} - {TitleName} ({TitleId:X16})";
Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance["DlcWindowTitle"]} - {_titleName} ({_titleId:X16})";
}
public DownloadableContentManagerWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName)
{
_virtualFileSystem = virtualFileSystem;
_downloadableContents = new AvaloniaList<DownloadableContentModel>();
TitleId = titleId;
TitleName = titleName;
_titleId = titleId;
_titleName = titleName;
_downloadableContentJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "dlc.json");
@@ -74,7 +72,7 @@ namespace Ryujinx.Ava.Ui.Windows
DlcDataGrid.SelectionChanged += DlcDataGrid_SelectionChanged;
Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance["DlcWindowTitle"]} - {TitleName} ({TitleId:X16})";
Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance["DlcWindowTitle"]} - {_titleName} ({_titleId:X16})";
LoadDownloadableContents();
PrintHeading();
@@ -87,7 +85,7 @@ namespace Ryujinx.Ava.Ui.Windows
private void PrintHeading()
{
Heading.Text = string.Format(LocaleManager.Instance["DlcWindowHeading"], _downloadableContents.Count, TitleName, TitleId.ToString("X16"));
Heading.Text = string.Format(LocaleManager.Instance["DlcWindowHeading"], _downloadableContents.Count, _titleName, _titleId.ToString("X16"));
}
private void LoadDownloadableContents()
@@ -98,15 +96,15 @@ namespace Ryujinx.Ava.Ui.Windows
{
using FileStream containerFile = File.OpenRead(downloadableContentContainer.ContainerPath);
PartitionFileSystem pfs = new(containerFile.AsStorage());
PartitionFileSystem partitionFileSystem = new(containerFile.AsStorage());
_virtualFileSystem.ImportTickets(pfs);
_virtualFileSystem.ImportTickets(partitionFileSystem);
foreach (DownloadableContentNca downloadableContentNca in downloadableContentContainer.DownloadableContentNcaList)
{
using UniqueRef<IFile> ncaFile = new();
pfs.OpenFile(ref ncaFile.Ref(), downloadableContentNca.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
partitionFileSystem.OpenFile(ref ncaFile.Ref(), downloadableContentNca.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), downloadableContentContainer.ContainerPath);
if (nca != null)
@@ -169,7 +167,7 @@ namespace Ryujinx.Ava.Ui.Windows
if (nca.Header.ContentType == NcaContentType.PublicData)
{
if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != TitleId)
if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != _titleId)
{
break;
}

View File

@@ -3,13 +3,17 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
SizeToContent="Height"
Width="600" MinHeight="500" Height="500"
WindowStartupLocation="CenterOwner"
Width="600"
Height="400"
MinWidth="600"
MinHeight="400"
MaxWidth="600"
MaxHeight="400"
SizeToContent="Height"
WindowStartupLocation="CenterOwner"
mc:Ignorable="d">
<Grid Margin="15">
<Grid.RowDefinitions>
@@ -19,15 +23,15 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Name="Heading"
Grid.Row="1"
MaxWidth="500"
Margin="20,15,20,20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
MaxWidth="500"
LineHeight="18"
TextWrapping="Wrap"
Text="{Binding Heading}"
TextAlignment="Center" />
TextAlignment="Center"
TextWrapping="Wrap" />
<Border
Grid.Row="2"
Margin="5"
@@ -36,8 +40,6 @@
BorderBrush="Gray"
BorderThickness="1">
<ScrollViewer
Width="550"
MinHeight="200"
VerticalAlignment="Stretch"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
@@ -45,11 +47,19 @@
Margin="10"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Items="{Binding TitleUpdates}">
Items="{Binding _titleUpdates}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Padding="8, 0" VerticalContentAlignment="Center" GroupName="Update" IsChecked="{Binding IsEnabled, Mode=TwoWay}">
<Label Margin="0" VerticalAlignment="Center" Content="{Binding Label}" />
<RadioButton
Padding="8,0"
VerticalContentAlignment="Center"
GroupName="Update"
IsChecked="{Binding IsEnabled, Mode=TwoWay}">
<Label
Margin="0"
VerticalAlignment="Center"
Content="{Binding Label}"
FontSize="12" />
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>

View File

@@ -30,13 +30,11 @@ namespace Ryujinx.Ava.Ui.Windows
private readonly string _titleUpdateJsonPath;
private TitleUpdateMetadata _titleUpdateWindowData;
public VirtualFileSystem VirtualFileSystem { get; }
private VirtualFileSystem _virtualFileSystem { get; }
private AvaloniaList<TitleUpdateModel> _titleUpdates { get; set; }
internal AvaloniaList<TitleUpdateModel> TitleUpdates { get; set; } = new AvaloniaList<TitleUpdateModel>();
public string TitleId { get; }
public string TitleName { get; }
public string Heading => string.Format(LocaleManager.Instance["GameUpdateWindowHeading"], TitleName, TitleId.ToUpper());
private ulong _titleId { get; }
private string _titleName { get; }
public TitleUpdateWindow()
{
@@ -44,16 +42,18 @@ namespace Ryujinx.Ava.Ui.Windows
InitializeComponent();
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["UpdateWindowTitle"];
Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance["UpdateWindowTitle"]} - {_titleName} ({_titleId:X16})";
}
public TitleUpdateWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName)
public TitleUpdateWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName)
{
VirtualFileSystem = virtualFileSystem;
TitleId = titleId;
TitleName = titleName;
_virtualFileSystem = virtualFileSystem;
_titleUpdates = new AvaloniaList<TitleUpdateModel>();
_titleUpdateJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId, "updates.json");
_titleId = titleId;
_titleName = titleName;
_titleUpdateJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "updates.json");
try
{
@@ -64,7 +64,7 @@ namespace Ryujinx.Ava.Ui.Windows
_titleUpdateWindowData = new TitleUpdateMetadata
{
Selected = "",
Paths = new List<string>()
Paths = new List<string>()
};
}
@@ -72,14 +72,20 @@ namespace Ryujinx.Ava.Ui.Windows
InitializeComponent();
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["UpdateWindowTitle"];
Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance["UpdateWindowTitle"]} - {_titleName} ({_titleId:X16})";
LoadUpdates();
PrintHeading();
}
private void PrintHeading()
{
Heading.Text = string.Format(LocaleManager.Instance["GameUpdateWindowHeading"], _titleUpdates.Count, _titleName, _titleId.ToString("X16"));
}
private void LoadUpdates()
{
TitleUpdates.Add(new TitleUpdateModel(default, string.Empty, true));
_titleUpdates.Add(new TitleUpdateModel(default, string.Empty, true));
foreach (string path in _titleUpdateWindowData.Paths)
{
@@ -88,12 +94,12 @@ namespace Ryujinx.Ava.Ui.Windows
if (_titleUpdateWindowData.Selected == "")
{
TitleUpdates[0].IsEnabled = true;
_titleUpdates[0].IsEnabled = true;
}
else
{
TitleUpdateModel selected = TitleUpdates.FirstOrDefault(x => x.Path == _titleUpdateWindowData.Selected);
List<TitleUpdateModel> enabled = TitleUpdates.Where(x => x.IsEnabled).ToList();
TitleUpdateModel selected = _titleUpdates.FirstOrDefault(x => x.Path == _titleUpdateWindowData.Selected);
List<TitleUpdateModel> enabled = _titleUpdates.Where(x => x.IsEnabled).ToList();
foreach (TitleUpdateModel update in enabled)
{
@@ -111,50 +117,47 @@ namespace Ryujinx.Ava.Ui.Windows
private void AddUpdate(string path)
{
if (File.Exists(path) && !TitleUpdates.Any(x => x.Path == path))
if (File.Exists(path) && !_titleUpdates.Any(x => x.Path == path))
{
using (FileStream file = new(path, FileMode.Open, FileAccess.Read))
using FileStream file = new(path, FileMode.Open, FileAccess.Read);
try
{
PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage());
(Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateDataFromPartition(_virtualFileSystem, new PartitionFileSystem(file.AsStorage()), _titleId.ToString("x16"), 0);
try
if (controlNca != null && patchNca != null)
{
(Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateDataFromPartition(VirtualFileSystem, nsp, TitleId, 0);
ApplicationControlProperty controlData = new();
if (controlNca != null && patchNca != null)
using UniqueRef<IFile> nacpFile = new();
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref(), "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
_titleUpdates.Add(new TitleUpdateModel(controlData, path));
foreach (var update in _titleUpdates)
{
ApplicationControlProperty controlData = new ApplicationControlProperty();
using var nacpFile = new UniqueRef<IFile>();
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref(), "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
TitleUpdates.Add(new TitleUpdateModel(controlData, path));
foreach (var update in TitleUpdates)
{
update.IsEnabled = false;
}
TitleUpdates.Last().IsEnabled = true;
}
else
{
Dispatcher.UIThread.Post(async () =>
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogUpdateAddUpdateErrorMessage"]);
});
update.IsEnabled = false;
}
_titleUpdates.Last().IsEnabled = true;
}
catch (Exception ex)
else
{
Dispatcher.UIThread.Post(async () =>
{
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogDlcLoadNcaErrorMessage"], ex.Message, path));
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogUpdateAddUpdateErrorMessage"]);
});
}
}
catch (Exception ex)
{
Dispatcher.UIThread.Post(async () =>
{
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogDlcLoadNcaErrorMessage"], ex.Message, path));
});
}
}
}
@@ -162,16 +165,17 @@ namespace Ryujinx.Ava.Ui.Windows
{
if (removeSelectedOnly)
{
TitleUpdates.RemoveAll(TitleUpdates.Where(x => x.IsEnabled && !x.IsNoUpdate).ToList());
_titleUpdates.RemoveAll(_titleUpdates.Where(x => x.IsEnabled && !x.IsNoUpdate).ToList());
}
else
{
TitleUpdates.RemoveAll(TitleUpdates.Where(x => !x.IsNoUpdate).ToList());
_titleUpdates.RemoveAll(_titleUpdates.Where(x => !x.IsNoUpdate).ToList());
}
TitleUpdates.FirstOrDefault(x => x.IsNoUpdate).IsEnabled = true;
_titleUpdates.FirstOrDefault(x => x.IsNoUpdate).IsEnabled = true;
SortUpdates();
PrintHeading();
}
public void RemoveSelected()
@@ -186,7 +190,7 @@ namespace Ryujinx.Ava.Ui.Windows
public async void Add()
{
OpenFileDialog dialog = new OpenFileDialog()
OpenFileDialog dialog = new()
{
Title = LocaleManager.Instance["SelectUpdateDialogTitle"],
AllowMultiple = true
@@ -209,11 +213,12 @@ namespace Ryujinx.Ava.Ui.Windows
}
SortUpdates();
PrintHeading();
}
private void SortUpdates()
{
var list = TitleUpdates.ToList();
var list = _titleUpdates.ToList();
list.Sort((first, second) =>
{
@@ -229,8 +234,8 @@ namespace Ryujinx.Ava.Ui.Windows
return Version.Parse(first.Control.DisplayVersionString.ToString()).CompareTo(Version.Parse(second.Control.DisplayVersionString.ToString())) * -1;
});
TitleUpdates.Clear();
TitleUpdates.AddRange(list);
_titleUpdates.Clear();
_titleUpdates.AddRange(list);
}
public void Save()
@@ -239,7 +244,7 @@ namespace Ryujinx.Ava.Ui.Windows
_titleUpdateWindowData.Selected = "";
foreach (TitleUpdateModel update in TitleUpdates)
foreach (TitleUpdateModel update in _titleUpdates)
{
_titleUpdateWindowData.Paths.Add(update.Path);

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 3868;
private const uint CodeGenVersion = 3897;
private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";

View File

@@ -128,6 +128,11 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
GetStorageOffset(block, Utils.FindLastOperation(addrLow, block), baseAddressCbOffset) :
(null, 0);
if (byteOffset != null)
{
ReplaceAddressAlignment(node.List, addrLow, byteOffset, constantOffset);
}
if (byteOffset == null)
{
Operand baseAddrLow = Cbuf(0, baseAddressCbOffset);
@@ -156,11 +161,6 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
byteOffset = offset;
}
if (byteOffset != null)
{
ReplaceAddressAlignment(node.List, addrLow, byteOffset, constantOffset);
}
if (isStg16Or8)
{
return byteOffset;

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Ptm.Psm
{
if (_stateChangeEventHandle == -1)
{
KernelResult resultCode = context.Process.HandleTable.GenerateHandle(_stateChangeEvent.ReadableEvent, out int stateChangeEventHandle);
KernelResult resultCode = context.Process.HandleTable.GenerateHandle(_stateChangeEvent.ReadableEvent, out _stateChangeEventHandle);
if (resultCode != KernelResult.Success)
{

View File

@@ -315,6 +315,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
}
}
if (updateCount > 0)
{
break;
}
// If we are here, that mean nothing was availaible, sleep for 50ms
context.Device.System.KernelContext.Syscall.SleepThread(50 * 1000000);
}
@@ -972,11 +977,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
}
[CommandHipc(31)] // 7.0.0+
// EventFd(u64 initval, nn::socket::EventFdFlags flags) -> (i32 ret, u32 bsd_errno)
// EventFd(nn::socket::EventFdFlags flags, u64 initval) -> (i32 ret, u32 bsd_errno)
public ResultCode EventFd(ServiceCtx context)
{
ulong initialValue = context.RequestData.ReadUInt64();
EventFdFlags flags = (EventFdFlags)context.RequestData.ReadUInt32();
context.RequestData.BaseStream.Position += 4; // Padding
ulong initialValue = context.RequestData.ReadUInt64();
EventFileDescriptor newEventFile = new EventFileDescriptor(initialValue, flags);

View File

@@ -26,8 +26,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
_value = value;
_flags = flags;
WriteEvent = new ManualResetEvent(true);
ReadEvent = new ManualResetEvent(true);
WriteEvent = new ManualResetEvent(false);
ReadEvent = new ManualResetEvent(false);
UpdateEventStates();
}
public int Refcount { get; set; }
@@ -38,6 +39,25 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
ReadEvent.Dispose();
}
private void ResetEventStates()
{
WriteEvent.Reset();
ReadEvent.Reset();
}
private void UpdateEventStates()
{
if (_value > 0)
{
ReadEvent.Set();
}
if (_value != uint.MaxValue - 1)
{
WriteEvent.Set();
}
}
public LinuxError Read(out int readSize, Span<byte> buffer)
{
if (buffer.Length < sizeof(ulong))
@@ -47,10 +67,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
return LinuxError.EINVAL;
}
ReadEvent.Reset();
lock (_lock)
{
ResetEventStates();
ref ulong count = ref MemoryMarshal.Cast<byte, ulong>(buffer)[0];
if (_value == 0)
@@ -66,6 +86,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
readSize = 0;
UpdateEventStates();
return LinuxError.EAGAIN;
}
}
@@ -85,8 +106,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
_value = 0;
}
ReadEvent.Set();
UpdateEventStates();
return LinuxError.SUCCESS;
}
}
@@ -100,10 +120,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
return LinuxError.EINVAL;
}
WriteEvent.Reset();
lock (_lock)
{
ResetEventStates();
if (_value > _value + count)
{
if (Blocking)
@@ -114,6 +134,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
writeSize = 0;
UpdateEventStates();
return LinuxError.EAGAIN;
}
}
@@ -123,8 +144,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
_value += count;
Monitor.Pulse(_lock);
WriteEvent.Set();
UpdateEventStates();
return LinuxError.SUCCESS;
}
}

View File

@@ -68,20 +68,37 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
for (int i = 0; i < events.Count; i++)
{
PollEventTypeMask outputEvents = 0;
PollEvent evnt = events[i];
EventFileDescriptor socket = (EventFileDescriptor)evnt.FileDescriptor;
if ((evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Input) ||
evnt.Data.InputEvents.HasFlag(PollEventTypeMask.UrgentInput))
&& socket.ReadEvent.WaitOne(0))
if (socket.ReadEvent.WaitOne(0))
{
waiters.Add(socket.ReadEvent);
if (evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Input))
{
outputEvents |= PollEventTypeMask.Input;
}
if (evnt.Data.InputEvents.HasFlag(PollEventTypeMask.UrgentInput))
{
outputEvents |= PollEventTypeMask.UrgentInput;
}
}
if ((evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Output))
&& socket.WriteEvent.WaitOne(0))
{
waiters.Add(socket.WriteEvent);
outputEvents |= PollEventTypeMask.Output;
}
if (outputEvents != 0)
{
evnt.Data.OutputEvents = outputEvents;
updatedCount++;
}
}
}

View File

@@ -566,7 +566,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
private static List<AddrInfoSerialized> DeserializeAddrInfos(IVirtualMemoryManager memory, ulong address, ulong size)
{
List<AddrInfoSerialized> result = new List<AddrInfoSerialized>();
List<AddrInfoSerialized> result = new();
ReadOnlySpan<byte> data = memory.GetSpan(address, (int)size);
@@ -606,9 +606,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
}
// NOTE: 0 = Any
AddrInfoSerializedHeader header = new AddrInfoSerializedHeader(ip, 0);
AddrInfo4 addr = new AddrInfo4(ip, (short)port);
AddrInfoSerialized info = new AddrInfoSerialized(header, addr, null, hostEntry.HostName);
AddrInfoSerializedHeader header = new(ip, 0);
AddrInfo4 addr = new(ip, (short)port);
AddrInfoSerialized info = new(header, addr, null, hostEntry.HostName);
data = info.Write(data);
}

View File

@@ -14,6 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
public byte Family;
public short Port;
public Array4<byte> Address;
public Array8<byte> Padding;
public AddrInfo4(IPAddress address, short port)
{

View File

@@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
AddrInfo4? socketAddress = null;
Array4<byte>? rawIPv4Address = null;
string canonicalName = null;
string canonicalName;
buffer = buffer[Unsafe.SizeOf<AddrInfoSerializedHeader>()..];
@@ -50,6 +50,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
Debug.Assert(header.Magic == SfdnsresContants.AddrInfoMagic);
if (header.AddressLength == 0)
{
rest = buffer;
return null;
}
if (header.Family == (int)AddressFamily.InterNetwork)
{
socketAddress = MemoryMarshal.Read<AddrInfo4>(buffer);