Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ee174be57c | ||
|
0bcbe32367 | ||
|
b97ff4da5e | ||
|
747081d2c7 |
@@ -1,6 +1,6 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT16BImm11 : OpCode32, IOpCode32BImm
|
||||
class OpCodeT16BImm11 : OpCodeT16, IOpCode32BImm
|
||||
{
|
||||
public long Immediate { get; }
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT16BImm8 : OpCode32, IOpCode32BImm
|
||||
class OpCodeT16BImm8 : OpCodeT16, IOpCode32BImm
|
||||
{
|
||||
public long Immediate { get; }
|
||||
|
||||
|
@@ -197,7 +197,7 @@ namespace ARMeilleure.Instructions
|
||||
// ARM32.
|
||||
case IOpCode32AluImm op:
|
||||
{
|
||||
if (ShouldSetFlags(context) && op.IsRotated)
|
||||
if (ShouldSetFlags(context) && op.IsRotated && setCarry)
|
||||
{
|
||||
SetFlag(context, PState.CFlag, Const((uint)op.Immediate >> 31));
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||
|
||||
private const uint InternalVersion = 3138; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 3179; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
|
@@ -34,6 +34,7 @@ namespace Ryujinx.Common.Configuration
|
||||
private const string DefaultModsDir = "mods";
|
||||
|
||||
public static string CustomModsPath { get; set; }
|
||||
public static string CustomSdModsPath {get; set; }
|
||||
public static string CustomNandPath { get; set; } // TODO: Actually implement this into VFS
|
||||
public static string CustomSdCardPath { get; set; } // TODO: Actually implement this into VFS
|
||||
|
||||
@@ -84,6 +85,7 @@ namespace Ryujinx.Common.Configuration
|
||||
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));
|
||||
}
|
||||
|
||||
public static string GetModsPath() => CustomModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultModsDir)).FullName;
|
||||
public static string GetModsPath() => CustomModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultModsDir)).FullName;
|
||||
public static string GetSdModsPath() => CustomSdModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultSdcardDir, "atmosphere")).FullName;
|
||||
}
|
||||
}
|
@@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
/// <summary>
|
||||
/// Version of the codegen (to be changed when codegen or guest format change).
|
||||
/// </summary>
|
||||
private const ulong ShaderCodeGenVersion = 3132;
|
||||
private const ulong ShaderCodeGenVersion = 3054;
|
||||
|
||||
// Progress reporting helpers
|
||||
private volatile int _shaderCount;
|
||||
|
@@ -308,7 +308,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
int attr = offset + elemIndex * 4;
|
||||
if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
|
||||
{
|
||||
int index = (attr - AttributeConsts.UserAttributeBase) / 16;
|
||||
int userAttr = attr - AttributeConsts.UserAttributeBase;
|
||||
int index = userAttr / 16;
|
||||
|
||||
if (isStore)
|
||||
{
|
||||
@@ -316,7 +317,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||
}
|
||||
else
|
||||
{
|
||||
config.SetInputUserAttribute(index, perPatch);
|
||||
config.SetInputUserAttribute(index, (userAttr >> 2) & 3, perPatch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -54,6 +54,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
private int _nextUsedInputAttributes;
|
||||
private int _thisUsedInputAttributes;
|
||||
|
||||
public UInt128 NextInputAttributesComponents { get; private set; }
|
||||
public UInt128 ThisInputAttributesComponents { get; private set; }
|
||||
public UInt128 NextInputAttributesPerPatchComponents { get; private set; }
|
||||
public UInt128 ThisInputAttributesPerPatchComponents { get; private set; }
|
||||
|
||||
private int _usedConstantBuffers;
|
||||
private int _usedStorageBuffers;
|
||||
private int _usedStorageBuffersWrite;
|
||||
@@ -227,11 +232,12 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
UsedOutputAttributes |= 1 << index;
|
||||
}
|
||||
|
||||
public void SetInputUserAttribute(int index, bool perPatch)
|
||||
public void SetInputUserAttribute(int index, int component, bool perPatch)
|
||||
{
|
||||
if (perPatch)
|
||||
{
|
||||
UsedInputAttributesPerPatch |= 1 << index;
|
||||
ThisInputAttributesPerPatchComponents |= UInt128.Pow2(index * 4 + component);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -239,6 +245,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
|
||||
UsedInputAttributes |= mask;
|
||||
_thisUsedInputAttributes |= mask;
|
||||
ThisInputAttributesComponents |= UInt128.Pow2(index * 4 + component);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +263,8 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
|
||||
public void MergeFromtNextStage(ShaderConfig config)
|
||||
{
|
||||
NextInputAttributesComponents = config.ThisInputAttributesComponents;
|
||||
NextInputAttributesPerPatchComponents = config.ThisInputAttributesPerPatchComponents;
|
||||
NextUsesFixedFuncAttributes = config.UsedFeatures.HasFlag(FeatureFlags.FixedFuncAttr);
|
||||
MergeOutputUserAttributes(config.UsedInputAttributes, config.UsedInputAttributesPerPatch);
|
||||
}
|
||||
|
@@ -214,24 +214,24 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
InitializeOutput(context, AttributeConsts.PositionX, perPatch: false);
|
||||
}
|
||||
|
||||
int usedAttributes = context.Config.UsedOutputAttributes;
|
||||
while (usedAttributes != 0)
|
||||
UInt128 usedAttributes = context.Config.NextInputAttributesComponents;
|
||||
while (usedAttributes != UInt128.Zero)
|
||||
{
|
||||
int index = BitOperations.TrailingZeroCount(usedAttributes);
|
||||
int index = usedAttributes.TrailingZeroCount();
|
||||
|
||||
InitializeOutput(context, AttributeConsts.UserAttributeBase + index * 16, perPatch: false);
|
||||
InitializeOutputComponent(context, AttributeConsts.UserAttributeBase + index * 4, perPatch: false);
|
||||
|
||||
usedAttributes &= ~(1 << index);
|
||||
usedAttributes &= ~UInt128.Pow2(index);
|
||||
}
|
||||
|
||||
int usedAttributesPerPatch = context.Config.UsedOutputAttributesPerPatch;
|
||||
while (usedAttributesPerPatch != 0)
|
||||
UInt128 usedAttributesPerPatch = context.Config.NextInputAttributesPerPatchComponents;
|
||||
while (usedAttributesPerPatch != UInt128.Zero)
|
||||
{
|
||||
int index = BitOperations.TrailingZeroCount(usedAttributesPerPatch);
|
||||
int index = usedAttributesPerPatch.TrailingZeroCount();
|
||||
|
||||
InitializeOutput(context, AttributeConsts.UserAttributeBase + index * 16, perPatch: true);
|
||||
InitializeOutputComponent(context, AttributeConsts.UserAttributeBase + index * 4, perPatch: true);
|
||||
|
||||
usedAttributesPerPatch &= ~(1 << index);
|
||||
usedAttributesPerPatch &= ~UInt128.Pow2(index);
|
||||
}
|
||||
|
||||
if (config.NextUsesFixedFuncAttributes)
|
||||
@@ -260,6 +260,12 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitializeOutputComponent(EmitterContext context, int attrOffset, bool perPatch)
|
||||
{
|
||||
int c = (attrOffset >> 2) & 3;
|
||||
context.Copy(perPatch ? AttributePerPatch(attrOffset) : Attribute(attrOffset), ConstF(c == 3 ? 1f : 0f));
|
||||
}
|
||||
|
||||
private static void EmitOps(EmitterContext context, Block block)
|
||||
{
|
||||
for (int opIndex = 0; opIndex < block.OpCodes.Count; opIndex++)
|
||||
|
74
Ryujinx.Graphics.Shader/Translation/UInt128.cs
Normal file
74
Ryujinx.Graphics.Shader/Translation/UInt128.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader.Translation
|
||||
{
|
||||
struct UInt128 : IEquatable<UInt128>
|
||||
{
|
||||
public static UInt128 Zero => new UInt128() { _v0 = 0, _v1 = 0 };
|
||||
|
||||
private ulong _v0;
|
||||
private ulong _v1;
|
||||
|
||||
public int TrailingZeroCount()
|
||||
{
|
||||
int count = BitOperations.TrailingZeroCount(_v0);
|
||||
if (count == 64)
|
||||
{
|
||||
count += BitOperations.TrailingZeroCount(_v1);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public static UInt128 Pow2(int x)
|
||||
{
|
||||
if (x >= 64)
|
||||
{
|
||||
return new UInt128() { _v0 = 0, _v1 = 1UL << (x - 64 ) };
|
||||
}
|
||||
|
||||
return new UInt128() { _v0 = 1UL << x, _v1 = 0 };
|
||||
}
|
||||
|
||||
public static UInt128 operator ~(UInt128 x)
|
||||
{
|
||||
return new UInt128() { _v0 = ~x._v0, _v1 = ~x._v1 };
|
||||
}
|
||||
|
||||
public static UInt128 operator &(UInt128 x, UInt128 y)
|
||||
{
|
||||
return new UInt128() { _v0 = x._v0 & y._v0, _v1 = x._v1 & y._v1 };
|
||||
}
|
||||
|
||||
public static UInt128 operator |(UInt128 x, UInt128 y)
|
||||
{
|
||||
return new UInt128() { _v0 = x._v0 | y._v0, _v1 = x._v1 | y._v1 };
|
||||
}
|
||||
|
||||
public static bool operator ==(UInt128 x, UInt128 y)
|
||||
{
|
||||
return x.Equals(y);
|
||||
}
|
||||
|
||||
public static bool operator !=(UInt128 x, UInt128 y)
|
||||
{
|
||||
return !x.Equals(y);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is UInt128 other && Equals(other);
|
||||
}
|
||||
|
||||
public bool Equals(UInt128 other)
|
||||
{
|
||||
return _v0 == other._v0 && _v1 == other._v1;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(_v0, _v1);
|
||||
}
|
||||
}
|
||||
}
|
@@ -84,7 +84,10 @@ namespace Ryujinx.HLE.HOS
|
||||
|
||||
MetaLoader metaData = ReadNpdm(codeFs);
|
||||
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.CollectMods(new[] { TitleId }, _device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath());
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.CollectMods(
|
||||
new[] { TitleId },
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath(),
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.GetSdModsBasePath());
|
||||
|
||||
if (TitleId != 0)
|
||||
{
|
||||
@@ -388,7 +391,10 @@ namespace Ryujinx.HLE.HOS
|
||||
|
||||
MetaLoader metaData = ReadNpdm(codeFs);
|
||||
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.CollectMods(_device.Configuration.ContentManager.GetAocTitleIds().Prepend(TitleId), _device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath());
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.CollectMods(
|
||||
_device.Configuration.ContentManager.GetAocTitleIds().Prepend(TitleId),
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath(),
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.GetSdModsBasePath());
|
||||
|
||||
if (controlNca != null)
|
||||
{
|
||||
|
@@ -136,7 +136,8 @@ namespace Ryujinx.HLE.HOS
|
||||
|
||||
private static bool StrEquals(string s1, string s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
public string GetModsBasePath() => EnsureBaseDirStructure(AppDataManager.GetModsPath());
|
||||
public string GetModsBasePath() => EnsureBaseDirStructure(AppDataManager.GetModsPath());
|
||||
public string GetSdModsBasePath() => EnsureBaseDirStructure(AppDataManager.GetSdModsPath());
|
||||
|
||||
private string EnsureBaseDirStructure(string modsBasePath)
|
||||
{
|
||||
|
57
Ryujinx.Tests/Cpu/CpuTestAluImm32.cs
Normal file
57
Ryujinx.Tests/Cpu/CpuTestAluImm32.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
#define AluRs32
|
||||
|
||||
using NUnit.Framework;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
[Category("AluImm32")]
|
||||
public sealed class CpuTestAluImm32 : CpuTest32
|
||||
{
|
||||
#if AluRs32
|
||||
|
||||
#region "ValueSource (Opcodes)"
|
||||
private static uint[] _opcodes()
|
||||
{
|
||||
return new uint[]
|
||||
{
|
||||
0xe2a00000u, // ADC R0, R0, #0
|
||||
0xe2b00000u, // ADCS R0, R0, #0
|
||||
0xe2800000u, // ADD R0, R0, #0
|
||||
0xe2900000u, // ADDS R0, R0, #0
|
||||
0xe3c00000u, // BIC R0, R0, #0
|
||||
0xe3d00000u, // BICS R0, R0, #0
|
||||
0xe2600000u, // RSB R0, R0, #0
|
||||
0xe2700000u, // RSBS R0, R0, #0
|
||||
0xe2e00000u, // RSC R0, R0, #0
|
||||
0xe2f00000u, // RSCS R0, R0, #0
|
||||
0xe2c00000u, // SBC R0, R0, #0
|
||||
0xe2d00000u, // SBCS R0, R0, #0
|
||||
0xe2400000u, // SUB R0, R0, #0
|
||||
0xe2500000u, // SUBS R0, R0, #0
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
||||
private const int RndCnt = 2;
|
||||
private const int RndCntAmount = 2;
|
||||
|
||||
[Test, Pairwise]
|
||||
public void TestCpuTestAluImm32([ValueSource("_opcodes")] uint opcode,
|
||||
[Values(0u, 13u)] uint rd,
|
||||
[Values(1u, 13u)] uint rn,
|
||||
[Random(RndCnt)] uint imm,
|
||||
[Random(RndCnt)] uint wn,
|
||||
[Values(true, false)] bool carryIn)
|
||||
{
|
||||
opcode |= ((imm & 0xfff) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
|
||||
|
||||
uint sp = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
SingleOpcode(opcode, r1: wn, sp: sp, carry: carryIn);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
11
Ryujinx/Ui/Widgets/GameTableContextMenu.Designer.cs
generated
11
Ryujinx/Ui/Widgets/GameTableContextMenu.Designer.cs
generated
@@ -11,6 +11,7 @@ namespace Ryujinx.Ui.Widgets
|
||||
private MenuItem _manageDlcMenuItem;
|
||||
private MenuItem _manageCheatMenuItem;
|
||||
private MenuItem _openTitleModDirMenuItem;
|
||||
private MenuItem _openTitleSdModDirMenuItem;
|
||||
private Menu _extractSubMenu;
|
||||
private MenuItem _extractMenuItem;
|
||||
private MenuItem _extractRomFsMenuItem;
|
||||
@@ -88,6 +89,15 @@ namespace Ryujinx.Ui.Widgets
|
||||
};
|
||||
_openTitleModDirMenuItem.Activated += OpenTitleModDir_Clicked;
|
||||
|
||||
//
|
||||
// _openTitleSdModDirMenuItem
|
||||
//
|
||||
_openTitleSdModDirMenuItem = new MenuItem("Open Atmosphere Mods Directory")
|
||||
{
|
||||
TooltipText = "Open the alternative SD card atmosphere directory which contains the Application's Mods."
|
||||
};
|
||||
_openTitleSdModDirMenuItem.Activated += OpenTitleSdModDir_Clicked;
|
||||
|
||||
//
|
||||
// _extractSubMenu
|
||||
//
|
||||
@@ -199,6 +209,7 @@ namespace Ryujinx.Ui.Widgets
|
||||
Add(_manageDlcMenuItem);
|
||||
Add(_manageCheatMenuItem);
|
||||
Add(_openTitleModDirMenuItem);
|
||||
Add(_openTitleSdModDirMenuItem);
|
||||
Add(new SeparatorMenuItem());
|
||||
Add(_manageCacheMenuItem);
|
||||
Add(_extractMenuItem);
|
||||
|
@@ -477,6 +477,14 @@ namespace Ryujinx.Ui.Widgets
|
||||
OpenHelper.OpenFolder(titleModsPath);
|
||||
}
|
||||
|
||||
private void OpenTitleSdModDir_Clicked(object sender, EventArgs args)
|
||||
{
|
||||
string sdModsBasePath = _virtualFileSystem.ModLoader.GetSdModsBasePath();
|
||||
string titleModsPath = _virtualFileSystem.ModLoader.GetTitleDir(sdModsBasePath, _titleIdText);
|
||||
|
||||
OpenHelper.OpenFolder(titleModsPath);
|
||||
}
|
||||
|
||||
private void ExtractRomFs_Clicked(object sender, EventArgs args)
|
||||
{
|
||||
ExtractSection(NcaSectionType.Data);
|
||||
|
Reference in New Issue
Block a user