From c5f872c70a6b10c98c5710b8ecde04fb6b8ac340 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Thu, 16 Jan 2020 15:08:39 -0700 Subject: [PATCH 1/3] Update to LibHac 0.8.2 (#889) * Update to LibHac 0.8.2 This brings support for temporary savedata, ignores case in key names when loading from a file, and prints the rights ID correctly when missing a title key. * Auto-format IFileSystemProxy --- .../HOS/Services/Fs/IFileSystemProxy.cs | 68 +++++++++---------- Ryujinx.HLE/Ryujinx.HLE.csproj | 2 +- Ryujinx/Ui/SaveImporter.cs | 3 +- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs index 4e96788644..02743a47b7 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs @@ -37,9 +37,9 @@ namespace Ryujinx.HLE.HOS.Services.Fs public ResultCode OpenFileSystemWithId(ServiceCtx context) { FileSystemType fileSystemType = (FileSystemType)context.RequestData.ReadInt32(); - long titleId = context.RequestData.ReadInt64(); - string switchPath = ReadUtf8String(context); - string fullPath = context.Device.FileSystem.SwitchPathToSystemPath(switchPath); + long titleId = context.RequestData.ReadInt64(); + string switchPath = ReadUtf8String(context); + string fullPath = context.Device.FileSystem.SwitchPathToSystemPath(switchPath); if (!File.Exists(fullPath)) { @@ -59,7 +59,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs } FileStream fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read); - string extension = Path.GetExtension(fullPath); + string extension = Path.GetExtension(fullPath); if (extension == ".nca") { @@ -129,8 +129,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs [Command(22)] public ResultCode CreateSaveDataFileSystem(ServiceCtx context) { - SaveDataAttribute attribute = context.RequestData.ReadStruct(); - SaveDataCreateInfo createInfo = context.RequestData.ReadStruct(); + SaveDataAttribute attribute = context.RequestData.ReadStruct(); + SaveDataCreationInfo creationInfo = context.RequestData.ReadStruct(); SaveMetaCreateInfo metaCreateInfo = context.RequestData.ReadStruct(); // TODO: There's currently no program registry for FS to reference. @@ -140,14 +140,14 @@ namespace Ryujinx.HLE.HOS.Services.Fs attribute.TitleId = new TitleId(context.Process.TitleId); } - if (createInfo.OwnerId == TitleId.Zero) + if (creationInfo.OwnerId == TitleId.Zero) { - createInfo.OwnerId = new TitleId(context.Process.TitleId); + creationInfo.OwnerId = new TitleId(context.Process.TitleId); } Logger.PrintInfo(LogClass.ServiceFs, $"Creating save with title ID {attribute.TitleId.Value:x16}"); - Result result = _baseFileSystemProxy.CreateSaveDataFileSystem(ref attribute, ref createInfo, ref metaCreateInfo); + Result result = _baseFileSystemProxy.CreateSaveDataFileSystem(ref attribute, ref creationInfo, ref metaCreateInfo); return (ResultCode)result.Value; } @@ -155,10 +155,10 @@ namespace Ryujinx.HLE.HOS.Services.Fs [Command(23)] public ResultCode CreateSaveDataFileSystemBySystemSaveDataId(ServiceCtx context) { - SaveDataAttribute attribute = context.RequestData.ReadStruct(); - SaveDataCreateInfo createInfo = context.RequestData.ReadStruct(); + SaveDataAttribute attribute = context.RequestData.ReadStruct(); + SaveDataCreationInfo creationInfo = context.RequestData.ReadStruct(); - Result result = _baseFileSystemProxy.CreateSaveDataFileSystemBySystemSaveDataId(ref attribute, ref createInfo); + Result result = _baseFileSystemProxy.CreateSaveDataFileSystemBySystemSaveDataId(ref attribute, ref creationInfo); return (ResultCode)result.Value; } @@ -166,8 +166,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs [Command(25)] public ResultCode DeleteSaveDataFileSystemBySaveDataSpaceId(ServiceCtx context) { - SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); - ulong saveDataId = context.RequestData.ReadUInt64(); + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + ulong saveDataId = context.RequestData.ReadUInt64(); Result result = _baseFileSystemProxy.DeleteSaveDataFileSystemBySaveDataSpaceId(spaceId, saveDataId); @@ -177,7 +177,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs [Command(28)] public ResultCode DeleteSaveDataFileSystemBySaveDataAttribute(ServiceCtx context) { - SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); SaveDataAttribute attribute = context.RequestData.ReadStruct(); Result result = _baseFileSystemProxy.DeleteSaveDataFileSystemBySaveDataAttribute(spaceId, ref attribute); @@ -189,7 +189,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs // OpenGameCardStorage(u32, u32) -> object public ResultCode OpenGameCardStorage(ServiceCtx context) { - GameCardHandle handle = new GameCardHandle(context.RequestData.ReadInt32()); + GameCardHandle handle = new GameCardHandle(context.RequestData.ReadInt32()); GameCardPartitionRaw partitionId = (GameCardPartitionRaw)context.RequestData.ReadInt32(); Result result = _baseFileSystemProxy.OpenGameCardStorage(out LibHac.Fs.IStorage storage, handle, partitionId); @@ -205,10 +205,10 @@ namespace Ryujinx.HLE.HOS.Services.Fs [Command(35)] public ResultCode CreateSaveDataFileSystemWithHashSalt(ServiceCtx context) { - SaveDataAttribute attribute = context.RequestData.ReadStruct(); - SaveDataCreateInfo createInfo = context.RequestData.ReadStruct(); + SaveDataAttribute attribute = context.RequestData.ReadStruct(); + SaveDataCreationInfo creationInfo = context.RequestData.ReadStruct(); SaveMetaCreateInfo metaCreateInfo = context.RequestData.ReadStruct(); - HashSalt hashSalt = context.RequestData.ReadStruct(); + HashSalt hashSalt = context.RequestData.ReadStruct(); // TODO: There's currently no program registry for FS to reference. // Workaround that by setting the application ID and owner ID if they're not already set @@ -217,12 +217,12 @@ namespace Ryujinx.HLE.HOS.Services.Fs attribute.TitleId = new TitleId(context.Process.TitleId); } - if (createInfo.OwnerId == TitleId.Zero) + if (creationInfo.OwnerId == TitleId.Zero) { - createInfo.OwnerId = new TitleId(context.Process.TitleId); + creationInfo.OwnerId = new TitleId(context.Process.TitleId); } - Result result = _baseFileSystemProxy.CreateSaveDataFileSystemWithHashSalt(ref attribute, ref createInfo, ref metaCreateInfo, ref hashSalt); + Result result = _baseFileSystemProxy.CreateSaveDataFileSystemWithHashSalt(ref attribute, ref creationInfo, ref metaCreateInfo, ref hashSalt); return (ResultCode)result.Value; } @@ -231,7 +231,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs // OpenSaveDataFileSystem(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object saveDataFs public ResultCode OpenSaveDataFileSystem(ServiceCtx context) { - SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); SaveDataAttribute attribute = context.RequestData.ReadStruct(); // TODO: There's currently no program registry for FS to reference. @@ -242,7 +242,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs } Result result = _baseFileSystemProxy.OpenSaveDataFileSystem(out LibHac.Fs.IFileSystem fileSystem, spaceId, ref attribute); - + if (result.IsSuccess()) { MakeObject(context, new FileSystemProxy.IFileSystem(fileSystem)); @@ -255,7 +255,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs // OpenSaveDataFileSystemBySystemSaveDataId(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object systemSaveDataFs public ResultCode OpenSaveDataFileSystemBySystemSaveDataId(ServiceCtx context) { - SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); SaveDataAttribute attribute = context.RequestData.ReadStruct(); Result result = _baseFileSystemProxy.OpenSaveDataFileSystemBySystemSaveDataId(out LibHac.Fs.IFileSystem fileSystem, spaceId, ref attribute); @@ -324,10 +324,10 @@ namespace Ryujinx.HLE.HOS.Services.Fs public ResultCode FindSaveDataWithFilter(ServiceCtx context) { SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); - SaveDataFilter filter = context.RequestData.ReadStruct(); + SaveDataFilter filter = context.RequestData.ReadStruct(); long bufferPosition = context.Request.ReceiveBuff[0].Position; - long bufferLen = context.Request.ReceiveBuff[0].Size; + long bufferLen = context.Request.ReceiveBuff[0].Size; byte[] infoBuffer = new byte[bufferLen]; @@ -343,7 +343,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs public ResultCode OpenSaveDataInfoReaderWithFilter(ServiceCtx context) { SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); - SaveDataFilter filter = context.RequestData.ReadStruct(); + SaveDataFilter filter = context.RequestData.ReadStruct(); Result result = _baseFileSystemProxy.OpenSaveDataInfoReaderWithFilter(out LibHac.FsService.ISaveDataInfoReader infoReader, spaceId, ref filter); @@ -369,8 +369,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs public ResultCode OpenDataStorageByDataId(ServiceCtx context) { StorageId storageId = (StorageId)context.RequestData.ReadByte(); - byte[] padding = context.RequestData.ReadBytes(7); - long titleId = context.RequestData.ReadInt64(); + byte[] padding = context.RequestData.ReadBytes(7); + long titleId = context.RequestData.ReadInt64(); NcaContentType contentType = NcaContentType.Data; @@ -398,8 +398,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs { try { - LibHac.Fs.IStorage ncaStorage = new LocalStorage(ncaPath, FileAccess.Read, FileMode.Open); - Nca nca = new Nca(context.Device.System.KeySet, ncaStorage); + LibHac.Fs.IStorage ncaStorage = new LocalStorage(ncaPath, FileAccess.Read, FileMode.Open); + Nca nca = new Nca(context.Device.System.KeySet, ncaStorage); LibHac.Fs.IStorage romfsStorage = nca.OpenStorage(NcaSectionType.Data, context.Device.System.FsIntegrityCheckLevel); MakeObject(context, new FileSystemProxy.IStorage(romfsStorage)); @@ -412,12 +412,12 @@ namespace Ryujinx.HLE.HOS.Services.Fs return ResultCode.Success; } else - { + { throw new FileNotFoundException($"No Nca found in Path `{ncaPath}`."); } } else - { + { throw new DirectoryNotFoundException($"Path for title id {titleId:x16} on Storage {storageId} was not found in Path {installPath}."); } } diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj index 15c0c8c0c1..4fb4835d9c 100644 --- a/Ryujinx.HLE/Ryujinx.HLE.csproj +++ b/Ryujinx.HLE/Ryujinx.HLE.csproj @@ -52,7 +52,7 @@ - + diff --git a/Ryujinx/Ui/SaveImporter.cs b/Ryujinx/Ui/SaveImporter.cs index b0a5f64336..467cc4161d 100644 --- a/Ryujinx/Ui/SaveImporter.cs +++ b/Ryujinx/Ui/SaveImporter.cs @@ -3,7 +3,6 @@ using LibHac.Common; using LibHac.Fs; using LibHac.Fs.Shim; using LibHac.FsSystem; -using LibHac.FsSystem.Save; using LibHac.Ncm; using Ryujinx.HLE.Utilities; using System; @@ -131,7 +130,7 @@ namespace Ryujinx.Ui { SaveDataAttribute attribute = new SaveDataAttribute { - Type = SaveDataType.SaveData, + Type = SaveDataType.Account, UserId = userId, TitleId = new TitleId(titleId) }; From a5e20a8fd1de446d2948c500c95cf65b88a36687 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Fri, 17 Jan 2020 05:55:38 -0300 Subject: [PATCH 2/3] Add sampler border color support on the GPU (#893) --- Ryujinx.Graphics.Gpu/Image/Sampler.cs | 6 +++++- Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Ryujinx.Graphics.Gpu/Image/Sampler.cs b/Ryujinx.Graphics.Gpu/Image/Sampler.cs index 23c6160e39..45f5f519fb 100644 --- a/Ryujinx.Graphics.Gpu/Image/Sampler.cs +++ b/Ryujinx.Graphics.Gpu/Image/Sampler.cs @@ -30,7 +30,11 @@ namespace Ryujinx.Graphics.Gpu.Image CompareMode compareMode = descriptor.UnpackCompareMode(); CompareOp compareOp = descriptor.UnpackCompareOp(); - ColorF color = new ColorF(0, 0, 0, 0); + ColorF color = new ColorF( + descriptor.BorderColorR, + descriptor.BorderColorG, + descriptor.BorderColorB, + descriptor.BorderColorA); float minLod = descriptor.UnpackMinLod(); float maxLod = descriptor.UnpackMaxLod(); diff --git a/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs b/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs index 80b1b70fd5..77af1ce0fe 100644 --- a/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs +++ b/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs @@ -55,10 +55,10 @@ namespace Ryujinx.Graphics.Gpu.Image public uint Word1; public uint Word2; public uint Word3; - public uint BorderColorR; - public uint BorderColorG; - public uint BorderColorB; - public uint BorderColorA; + public float BorderColorR; + public float BorderColorG; + public float BorderColorB; + public float BorderColorA; /// /// Unpacks the texture wrap mode along the X axis. From 595e7716d8c1be786e7067c85b129827a2f89742 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Fri, 17 Jan 2020 06:07:27 -0300 Subject: [PATCH 3/3] Support audio effect output status (#890) * Support audio effect output status * Remove extra line --- .../AudioRendererManager/EffectContext.cs | 7 +++++ .../AudioRendererManager/IAudioRenderer.cs | 27 ++++++++++++++++--- .../AudioRendererManager/Types/EffectIn.cs | 12 +++++++++ .../AudioRendererManager/Types/EffectOut.cs | 11 ++++++++ .../AudioRendererManager/Types/EffectState.cs | 8 ++++++ 5 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/EffectContext.cs create mode 100644 Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectIn.cs create mode 100644 Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectOut.cs create mode 100644 Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectState.cs diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/EffectContext.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/EffectContext.cs new file mode 100644 index 0000000000..88f087ed1d --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/EffectContext.cs @@ -0,0 +1,7 @@ +namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager +{ + class EffectContext + { + public EffectOut OutStatus; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/IAudioRenderer.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/IAudioRenderer.cs index aa9b6e516e..379cf2dfb0 100644 --- a/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/IAudioRenderer.cs +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/IAudioRenderer.cs @@ -34,6 +34,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager private VoiceContext[] _voices; + private EffectContext[] _effects; + private int _track; private PlayState _playState; @@ -42,22 +44,24 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager Horizon system, MemoryManager memory, IAalOutput audioOut, - AudioRendererParameter Params) + AudioRendererParameter rendererParams) { _updateEvent = new KEvent(system); _memory = memory; _audioOut = audioOut; - _params = Params; + _params = rendererParams; _track = audioOut.OpenTrack( AudioRendererConsts.HostSampleRate, AudioRendererConsts.HostChannelsCount, AudioCallback); - _memoryPools = CreateArray(Params.EffectCount + Params.VoiceCount * 4); + _memoryPools = CreateArray(rendererParams.EffectCount + rendererParams.VoiceCount * 4); - _voices = CreateArray(Params.VoiceCount); + _voices = CreateArray(rendererParams.VoiceCount); + + _effects = CreateArray(rendererParams.EffectCount); InitializeAudioOut(); @@ -205,6 +209,16 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager voiceCtx.PlayState = voice.PlayState; } + EffectIn[] effectsIn = reader.Read(inputHeader.EffectSize); + + for (int index = 0; index < effectsIn.Length; index++) + { + if (effectsIn[index].IsNew != 0) + { + _effects[index].OutStatus.State = EffectState.New; + } + } + UpdateAudio(); UpdateDataHeader outputHeader = new UpdateDataHeader(); @@ -245,6 +259,11 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager writer.Write(voice.OutStatus); } + foreach (EffectContext effect in _effects) + { + writer.Write(effect.OutStatus); + } + return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectIn.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectIn.cs new file mode 100644 index 0000000000..0352047535 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectIn.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager +{ + [StructLayout(LayoutKind.Sequential, Size = 0xc0, Pack = 1)] + unsafe struct EffectIn + { + public byte Unknown0x0; + public byte IsNew; + public fixed byte Unknown[0xbe]; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectOut.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectOut.cs new file mode 100644 index 0000000000..5106ad9e33 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectOut.cs @@ -0,0 +1,11 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 1)] + unsafe struct EffectOut + { + public EffectState State; + public fixed byte Reserved[15]; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectState.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectState.cs new file mode 100644 index 0000000000..ed67668440 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/EffectState.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager +{ + enum EffectState : byte + { + None = 0, + New = 1 + } +}