Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
36172ab43b | |||
4d69286a9c | |||
1529e6cf0d | |||
f468db7602 | |||
c5f1d1749a | |||
7dd69f2d0e | |||
c646638680 | |||
65f2a82b97 | |||
93dd6d525a | |||
96d4ad952c | |||
6a07f80b76 | |||
22214ac664 | |||
45e520a27c | |||
5b5810a46a | |||
619ac86bd0 | |||
7a1ab71c73 | |||
dc4ba3993b | |||
81f1a4dc31 | |||
c64524a240 | |||
db45688aa8 | |||
c6d82209ab | |||
ee1825219b | |||
7baa08dcb4 | |||
408bd63b08 | |||
df99257d7f | |||
f3835dc78b | |||
51bb8707ef | |||
5ff5fe47ba | |||
38275f9056 | |||
67cbdc3a6a | |||
131b43170e | |||
730d2f4b9b | |||
f6a7309b14 | |||
472a621589 | |||
311c2661b8 | |||
a92e2028cb | |||
6922862db8 | |||
6592d64751 | |||
8001c832d9 | |||
87919b193c | |||
8de033e60e | |||
90432946ac | |||
9bad71afbf | |||
923089a298 | |||
d9aa15eb24 |
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Something doesn't work correctly in Ryujinx.
|
||||
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.
|
||||
#assignees:
|
||||
---
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using ARMeilleure.Diagnostics.EventSources;
|
||||
using ARMeilleure.Diagnostics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
@ -218,7 +218,7 @@ namespace ARMeilleure.Common
|
||||
|
||||
_pages.Add(page);
|
||||
|
||||
AddressTableEventSource.Log.Allocated(size, leaf);
|
||||
TranslatorEventSource.Log.AddressTableAllocated(size, leaf);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
@ -251,6 +251,13 @@ namespace ARMeilleure.Decoders
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare and branch instructions are always conditional.
|
||||
if (opCode.Instruction.Name == InstName.Cbz ||
|
||||
opCode.Instruction.Name == InstName.Cbnz)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: On ARM32, most instructions have conditional execution,
|
||||
// so there's no "Always" (unconditional) branch like on ARM64.
|
||||
// We need to check if the condition is "Always" instead.
|
||||
|
@ -151,7 +151,7 @@ namespace ARMeilleure.Decoders
|
||||
|
||||
public static bool VectorArgumentsInvalid(bool q, params int[] args)
|
||||
{
|
||||
if (q)
|
||||
if (q)
|
||||
{
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
|
@ -7,5 +7,8 @@
|
||||
|
||||
int Msb { get; }
|
||||
int Lsb { get; }
|
||||
|
||||
int SourceMask => (int)(0xFFFFFFFF >> (31 - Msb));
|
||||
int DestMask => SourceMask & (int)(0xFFFFFFFF << Lsb);
|
||||
}
|
||||
}
|
||||
|
7
ARMeilleure/Decoders/IOpCode32AluImm16.cs
Normal file
7
ARMeilleure/Decoders/IOpCode32AluImm16.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
interface IOpCode32AluImm16 : IOpCode32Alu
|
||||
{
|
||||
int Immediate { get; }
|
||||
}
|
||||
}
|
11
ARMeilleure/Decoders/IOpCode32AluMla.cs
Normal file
11
ARMeilleure/Decoders/IOpCode32AluMla.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
interface IOpCode32AluMla : IOpCode32AluReg
|
||||
{
|
||||
int Ra { get; }
|
||||
|
||||
bool NHigh { get; }
|
||||
bool MHigh { get; }
|
||||
bool R { get; }
|
||||
}
|
||||
}
|
13
ARMeilleure/Decoders/IOpCode32AluUmull.cs
Normal file
13
ARMeilleure/Decoders/IOpCode32AluUmull.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
interface IOpCode32AluUmull : IOpCode32, IOpCode32HasSetFlags
|
||||
{
|
||||
int RdLo { get; }
|
||||
int RdHi { get; }
|
||||
int Rn { get; }
|
||||
int Rm { get; }
|
||||
|
||||
bool NHigh { get; }
|
||||
bool MHigh { get; }
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ namespace ARMeilleure.Decoders
|
||||
interface IOpCode32Mem : IOpCode32
|
||||
{
|
||||
int Rt { get; }
|
||||
int Rt2 => Rt | 1;
|
||||
int Rn { get; }
|
||||
|
||||
bool WBack { get; }
|
||||
|
@ -13,16 +13,13 @@ namespace ARMeilleure.Decoders
|
||||
Cond = (Condition)((uint)opCode >> 28);
|
||||
}
|
||||
|
||||
public bool IsThumb()
|
||||
{
|
||||
return this is OpCodeT16 || this is OpCodeT32;
|
||||
}
|
||||
public bool IsThumb { get; protected init; } = false;
|
||||
|
||||
public uint GetPc()
|
||||
{
|
||||
// Due to backwards compatibility and legacy behavior of ARMv4 CPUs pipeline,
|
||||
// the PC actually points 2 instructions ahead.
|
||||
if (IsThumb())
|
||||
if (IsThumb)
|
||||
{
|
||||
// PC is ahead by 4 in thumb mode whether or not the current instruction
|
||||
// is 16 or 32 bit.
|
||||
|
@ -6,12 +6,8 @@
|
||||
public int Rn { get; }
|
||||
|
||||
public int Msb { get; }
|
||||
|
||||
public int Lsb { get; }
|
||||
|
||||
public int SourceMask => (int)(0xFFFFFFFF >> (31 - Msb));
|
||||
public int DestMask => SourceMask & (int)(0xFFFFFFFF << Lsb);
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32AluBf(inst, address, opCode);
|
||||
|
||||
public OpCode32AluBf(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCode32AluImm16 : OpCode32Alu
|
||||
class OpCode32AluImm16 : OpCode32Alu, IOpCode32AluImm16
|
||||
{
|
||||
public int Immediate { get; }
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCode32AluMla : OpCode32, IOpCode32AluReg
|
||||
class OpCode32AluMla : OpCode32, IOpCode32AluMla
|
||||
{
|
||||
public int Rn { get; }
|
||||
public int Rm { get; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCode32AluUmull : OpCode32, IOpCode32HasSetFlags
|
||||
class OpCode32AluUmull : OpCode32, IOpCode32AluUmull
|
||||
{
|
||||
public int RdLo { get; }
|
||||
public int RdHi { get; }
|
||||
@ -11,7 +11,6 @@
|
||||
public bool MHigh { get; }
|
||||
|
||||
public bool? SetFlags { get; }
|
||||
public DataOp DataOp { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32AluUmull(inst, address, opCode);
|
||||
|
||||
@ -26,7 +25,6 @@
|
||||
MHigh = ((opCode >> 6) & 0x1) == 1;
|
||||
|
||||
SetFlags = ((opCode >> 20) & 0x1) != 0;
|
||||
DataOp = DataOp.Arithmetic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,10 @@
|
||||
{
|
||||
class OpCode32SimdCvtFI : OpCode32SimdS
|
||||
{
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtFI(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtFI(inst, address, opCode, false);
|
||||
public new static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtFI(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdCvtFI(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdCvtFI(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
|
||||
{
|
||||
Opc = (opCode >> 7) & 0x1;
|
||||
|
||||
|
@ -7,10 +7,13 @@
|
||||
public int Rt { get; }
|
||||
public bool Q { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdDupGP(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdDupGP(inst, address, opCode, false);
|
||||
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdDupGP(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdDupGP(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdDupGP(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||
{
|
||||
IsThumb = isThumb;
|
||||
|
||||
Size = 2 - (((opCode >> 21) & 0x2) | ((opCode >> 5) & 0x1)); // B:E - 0 for 32, 16 then 8.
|
||||
if (Size == -1)
|
||||
{
|
||||
|
@ -7,10 +7,13 @@
|
||||
public int Size { get; }
|
||||
public int Elems { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdImm44(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdImm44(inst, address, opCode, false);
|
||||
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdImm44(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdImm44(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdImm44(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||
{
|
||||
IsThumb = isThumb;
|
||||
|
||||
Size = (opCode >> 8) & 0x3;
|
||||
|
||||
bool single = Size != 3;
|
||||
|
@ -8,10 +8,13 @@
|
||||
public bool Add { get; }
|
||||
public int Immediate { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMemImm(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMemImm(inst, address, opCode, false);
|
||||
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMemImm(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdMemImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdMemImm(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||
{
|
||||
IsThumb = isThumb;
|
||||
|
||||
Immediate = opCode & 0xff;
|
||||
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
|
@ -12,10 +12,13 @@
|
||||
public bool DoubleWidth { get; }
|
||||
public bool Add { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMemMult(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMemMult(inst, address, opCode, false);
|
||||
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMemMult(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdMemMult(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdMemMult(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||
{
|
||||
IsThumb = isThumb;
|
||||
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
|
||||
bool isLoad = (opCode & (1 << 20)) != 0;
|
||||
|
@ -11,10 +11,13 @@
|
||||
public int Opc1 { get; }
|
||||
public int Opc2 { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovGp(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovGp(inst, address, opCode, false);
|
||||
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovGp(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdMovGp(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdMovGp(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||
{
|
||||
IsThumb = isThumb;
|
||||
|
||||
// Which one is used is instruction dependant.
|
||||
Op = (opCode >> 20) & 0x1;
|
||||
|
||||
|
@ -9,10 +9,13 @@
|
||||
public int Rt2 { get; }
|
||||
public int Op { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovGpDouble(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovGpDouble(inst, address, opCode, false);
|
||||
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovGpDouble(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdMovGpDouble(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdMovGpDouble(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||
{
|
||||
IsThumb = isThumb;
|
||||
|
||||
// Which one is used is instruction dependant.
|
||||
Op = (opCode >> 20) & 0x1;
|
||||
|
||||
|
@ -11,10 +11,13 @@
|
||||
|
||||
public int Index { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovGpElem(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovGpElem(inst, address, opCode, false);
|
||||
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovGpElem(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdMovGpElem(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdMovGpElem(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||
{
|
||||
IsThumb = isThumb;
|
||||
|
||||
Op = (opCode >> 20) & 0x1;
|
||||
U = ((opCode >> 23) & 1) != 0;
|
||||
|
||||
|
12
ARMeilleure/Decoders/OpCode32SimdMovn.cs
Normal file
12
ARMeilleure/Decoders/OpCode32SimdMovn.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCode32SimdMovn : OpCode32Simd
|
||||
{
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdMovn(inst, address, opCode);
|
||||
|
||||
public OpCode32SimdMovn(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Size = (opCode >> 18) & 0x3;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,9 +4,10 @@
|
||||
{
|
||||
public int Vn { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdRegS(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdRegS(inst, address, opCode, false);
|
||||
public new static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdRegS(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdRegS(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdRegS(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
|
||||
{
|
||||
bool single = Size != 3;
|
||||
if (single)
|
||||
|
@ -8,10 +8,13 @@
|
||||
public int Opc2 { get; } // opc2 or RM (opc2<1:0>) [Vcvt, Vrint].
|
||||
public int Size { get; protected set; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdS(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdS(inst, address, opCode, false);
|
||||
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdS(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdS(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdS(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||
{
|
||||
IsThumb = isThumb;
|
||||
|
||||
Opc = (opCode >> 15) & 0x3;
|
||||
Opc2 = (opCode >> 16) & 0x7;
|
||||
|
||||
|
@ -4,9 +4,10 @@
|
||||
{
|
||||
public OpCode32SimdSelMode Cc { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdSel(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdSel(inst, address, opCode, false);
|
||||
public new static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdSel(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdSel(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdSel(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
|
||||
{
|
||||
Cc = (OpCode32SimdSelMode)((opCode >> 20) & 3);
|
||||
}
|
||||
|
@ -5,10 +5,13 @@
|
||||
public int Rt { get; }
|
||||
public int Sreg { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdSpecial(inst, address, opCode);
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdSpecial(inst, address, opCode, false);
|
||||
public static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdSpecial(inst, address, opCode, true);
|
||||
|
||||
public OpCode32SimdSpecial(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdSpecial(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
|
||||
{
|
||||
IsThumb = isThumb;
|
||||
|
||||
Rt = (opCode >> 12) & 0xf;
|
||||
Sreg = (opCode >> 16) & 0xf;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ namespace ARMeilleure.Decoders
|
||||
{
|
||||
Cond = Condition.Al;
|
||||
|
||||
IsThumb = true;
|
||||
OpCodeSizeInBytes = 2;
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,13 @@ namespace ARMeilleure.Decoders
|
||||
{
|
||||
public int Rd { get; }
|
||||
|
||||
public bool Add => true;
|
||||
public int Immediate { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16Adr(inst, address, opCode);
|
||||
|
||||
public OpCodeT16Adr(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rd = (opCode >> 8) & 7;
|
||||
Rd = (opCode >> 8) & 7;
|
||||
|
||||
int imm = (opCode & 0xff) << 2;
|
||||
Immediate = (int)(GetPc() & 0xfffffffc) + imm;
|
||||
|
@ -8,6 +8,7 @@
|
||||
{
|
||||
Cond = Condition.Al;
|
||||
|
||||
IsThumb = true;
|
||||
OpCodeSizeInBytes = 4;
|
||||
}
|
||||
}
|
||||
|
22
ARMeilleure/Decoders/OpCodeT32AluBf.cs
Normal file
22
ARMeilleure/Decoders/OpCodeT32AluBf.cs
Normal file
@ -0,0 +1,22 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT32AluBf : OpCodeT32, IOpCode32AluBf
|
||||
{
|
||||
public int Rd { get; }
|
||||
public int Rn { get; }
|
||||
|
||||
public int Msb { get; }
|
||||
public int Lsb { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluBf(inst, address, opCode);
|
||||
|
||||
public OpCodeT32AluBf(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rd = (opCode >> 8) & 0xf;
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
|
||||
Msb = (opCode >> 0) & 0x1f;
|
||||
Lsb = ((opCode >> 6) & 0x3) | ((opCode >> 10) & 0x1c);
|
||||
}
|
||||
}
|
||||
}
|
16
ARMeilleure/Decoders/OpCodeT32AluImm12.cs
Normal file
16
ARMeilleure/Decoders/OpCodeT32AluImm12.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT32AluImm12 : OpCodeT32Alu, IOpCode32AluImm
|
||||
{
|
||||
public int Immediate { get; }
|
||||
|
||||
public bool IsRotated => false;
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluImm12(inst, address, opCode);
|
||||
|
||||
public OpCodeT32AluImm12(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Immediate = (opCode & 0xff) | ((opCode >> 4) & 0x700) | ((opCode >> 15) & 0x800);
|
||||
}
|
||||
}
|
||||
}
|
29
ARMeilleure/Decoders/OpCodeT32AluMla.cs
Normal file
29
ARMeilleure/Decoders/OpCodeT32AluMla.cs
Normal file
@ -0,0 +1,29 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT32AluMla : OpCodeT32, IOpCode32AluMla
|
||||
{
|
||||
public int Rn { get; }
|
||||
public int Rm { get; }
|
||||
public int Ra { get; }
|
||||
public int Rd { get; }
|
||||
|
||||
public bool NHigh { get; }
|
||||
public bool MHigh { get; }
|
||||
public bool R { get; }
|
||||
public bool? SetFlags => false;
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluMla(inst, address, opCode);
|
||||
|
||||
public OpCodeT32AluMla(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rm = (opCode >> 0) & 0xf;
|
||||
Rd = (opCode >> 8) & 0xf;
|
||||
Ra = (opCode >> 12) & 0xf;
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
R = (opCode & (1 << 4)) != 0;
|
||||
|
||||
MHigh = ((opCode >> 4) & 0x1) == 1;
|
||||
NHigh = ((opCode >> 5) & 0x1) == 1;
|
||||
}
|
||||
}
|
||||
}
|
14
ARMeilleure/Decoders/OpCodeT32AluReg.cs
Normal file
14
ARMeilleure/Decoders/OpCodeT32AluReg.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT32AluReg : OpCodeT32Alu, IOpCode32AluReg
|
||||
{
|
||||
public int Rm { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluReg(inst, address, opCode);
|
||||
|
||||
public OpCodeT32AluReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rm = (opCode >> 0) & 0xf;
|
||||
}
|
||||
}
|
||||
}
|
28
ARMeilleure/Decoders/OpCodeT32AluUmull.cs
Normal file
28
ARMeilleure/Decoders/OpCodeT32AluUmull.cs
Normal file
@ -0,0 +1,28 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT32AluUmull : OpCodeT32, IOpCode32AluUmull
|
||||
{
|
||||
public int RdLo { get; }
|
||||
public int RdHi { get; }
|
||||
public int Rn { get; }
|
||||
public int Rm { get; }
|
||||
|
||||
public bool NHigh { get; }
|
||||
public bool MHigh { get; }
|
||||
|
||||
public bool? SetFlags => false;
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluUmull(inst, address, opCode);
|
||||
|
||||
public OpCodeT32AluUmull(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rm = (opCode >> 0) & 0xf;
|
||||
RdHi = (opCode >> 8) & 0xf;
|
||||
RdLo = (opCode >> 12) & 0xf;
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
|
||||
MHigh = ((opCode >> 4) & 0x1) == 1;
|
||||
NHigh = ((opCode >> 5) & 0x1) == 1;
|
||||
}
|
||||
}
|
||||
}
|
18
ARMeilleure/Decoders/OpCodeT32AluUx.cs
Normal file
18
ARMeilleure/Decoders/OpCodeT32AluUx.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using ARMeilleure.State;
|
||||
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT32AluUx : OpCodeT32AluReg, IOpCode32AluUx
|
||||
{
|
||||
public int Rotate { get; }
|
||||
public int RotateBits => Rotate * 8;
|
||||
public bool Add => Rn != RegisterAlias.Aarch32Pc;
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluUx(inst, address, opCode);
|
||||
|
||||
public OpCodeT32AluUx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rotate = (opCode >> 4) & 0x3;
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ namespace ARMeilleure.Decoders
|
||||
int i2 = j2 ^ s ^ 1;
|
||||
|
||||
int imm32 = imm11 | (imm10 << 11) | (i2 << 21) | (i1 << 22) | (s << 23);
|
||||
imm32 = (imm32 << 9) >> 8;
|
||||
imm32 = (imm32 << 8) >> 7;
|
||||
|
||||
Immediate = pc + imm32;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ namespace ARMeilleure.Decoders
|
||||
Add = ((opCode >> 23) & 1) != 0;
|
||||
WBack = ((opCode >> 21) & 1) != 0;
|
||||
|
||||
Immediate = opCode & 0xff;
|
||||
Immediate = (opCode & 0xff) << 2;
|
||||
|
||||
IsLoad = ((opCode >> 20) & 1) != 0;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace ARMeilleure.Decoders
|
||||
{
|
||||
public int Rd => 0;
|
||||
public int Rt { get; }
|
||||
public int Rt2 { get; }
|
||||
public int Rn { get; }
|
||||
|
||||
public bool WBack => false;
|
||||
@ -17,6 +18,7 @@ namespace ARMeilleure.Decoders
|
||||
|
||||
public OpCodeT32MemLdEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rt2 = (opCode >> 8) & 0xf;
|
||||
Rt = (opCode >> 12) & 0xf;
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace ARMeilleure.Decoders
|
||||
{
|
||||
public int Rd { get; }
|
||||
public int Rt { get; }
|
||||
public int Rt2 { get; }
|
||||
public int Rn { get; }
|
||||
|
||||
public bool WBack => false;
|
||||
@ -18,6 +19,7 @@ namespace ARMeilleure.Decoders
|
||||
public OpCodeT32MemStEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rd = (opCode >> 0) & 0xf;
|
||||
Rt2 = (opCode >> 8) & 0xf;
|
||||
Rt = (opCode >> 12) & 0xf;
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
}
|
||||
|
16
ARMeilleure/Decoders/OpCodeT32MovImm16.cs
Normal file
16
ARMeilleure/Decoders/OpCodeT32MovImm16.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT32MovImm16 : OpCodeT32Alu, IOpCode32AluImm16
|
||||
{
|
||||
public int Immediate { get; }
|
||||
|
||||
public bool IsRotated => false;
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MovImm16(inst, address, opCode);
|
||||
|
||||
public OpCodeT32MovImm16(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Immediate = (opCode & 0xff) | ((opCode >> 4) & 0x700) | ((opCode >> 15) & 0x800) | ((opCode >> 4) & 0xf000);
|
||||
}
|
||||
}
|
||||
}
|
19
ARMeilleure/Decoders/OpCodeT32ShiftReg.cs
Normal file
19
ARMeilleure/Decoders/OpCodeT32ShiftReg.cs
Normal file
@ -0,0 +1,19 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT32ShiftReg : OpCodeT32Alu, IOpCode32AluRsReg
|
||||
{
|
||||
public int Rm => Rn;
|
||||
public int Rs { get; }
|
||||
|
||||
public ShiftType ShiftType { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32ShiftReg(inst, address, opCode);
|
||||
|
||||
public OpCodeT32ShiftReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rs = (opCode >> 0) & 0xf;
|
||||
|
||||
ShiftType = (ShiftType)((opCode >> 21) & 3);
|
||||
}
|
||||
}
|
||||
}
|
16
ARMeilleure/Decoders/OpCodeT32Tb.cs
Normal file
16
ARMeilleure/Decoders/OpCodeT32Tb.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT32Tb : OpCodeT32, IOpCode32BReg
|
||||
{
|
||||
public int Rm { get; }
|
||||
public int Rn { get; }
|
||||
|
||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32Tb(inst, address, opCode);
|
||||
|
||||
public OpCodeT32Tb(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Rm = (opCode >> 0) & 0xf;
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
}
|
||||
}
|
||||
}
|
@ -792,7 +792,61 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("<<<<01101100xxxxxxxxxx000111xxxx", InstName.Uxtb16, InstEmit32.Uxtb16, OpCode32AluUx.Create);
|
||||
SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, OpCode32AluUx.Create);
|
||||
|
||||
// FP & SIMD
|
||||
// VFP
|
||||
SetVfp("<<<<11101x110000xxxx101x11x0xxxx", InstName.Vabs, InstEmit32.Vabs_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
SetVfp("<<<<11100x11xxxxxxxx101xx0x0xxxx", InstName.Vadd, InstEmit32.Vadd_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11101x11010xxxxx101x01x0xxxx", InstName.Vcmp, InstEmit32.Vcmp, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
SetVfp("<<<<11101x11010xxxxx101x11x0xxxx", InstName.Vcmpe, InstEmit32.Vcmpe, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
SetVfp("<<<<11101x110111xxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FD, OpCode32SimdS.Create, OpCode32SimdS.CreateT32); // FP 32 and 64, scalar.
|
||||
SetVfp("<<<<11101x11110xxxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create, OpCode32SimdCvtFI.CreateT32); // FP32 to int.
|
||||
SetVfp("<<<<11101x111000xxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create, OpCode32SimdCvtFI.CreateT32); // Int to FP32.
|
||||
SetVfp("111111101x1111xxxxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_RM, OpCode32SimdCvtFI.Create, OpCode32SimdCvtFI.CreateT32); // The many FP32 to int encodings (fp).
|
||||
SetVfp("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, OpCode32SimdDupGP.Create, OpCode32SimdDupGP.CreateT32);
|
||||
SetVfp("<<<<11101x10xxxxxxxx101xx0x0xxxx", InstName.Vfma, InstEmit32.Vfma_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11101x10xxxxxxxx101xx1x0xxxx", InstName.Vfms, InstEmit32.Vfms_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11101x01xxxxxxxx101xx1x0xxxx", InstName.Vfnma, InstEmit32.Vfnma_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11101x01xxxxxxxx101xx0x0xxxx", InstName.Vfnms, InstEmit32.Vfnms_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11001x01xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11001x11xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11010x11xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11001x01xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11001x11xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11010x11xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<1101xx01xxxxxxxx101xxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, OpCode32SimdMemImm.Create, OpCode32SimdMemImm.CreateT32);
|
||||
SetVfp("111111101x00xxxxxxxx10>>x0x0xxxx", InstName.Vmaxnm, InstEmit32.Vmaxnm_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("111111101x00xxxxxxxx10>>x1x0xxxx", InstName.Vminnm, InstEmit32.Vminnm_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11100x00xxxxxxxx101xx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11100x00xxxxxxxx101xx1x0xxxx", InstName.Vmls, InstEmit32.Vmls_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11100xx0xxxxxxxx1011xxx10000", InstName.Vmov, InstEmit32.Vmov_G1, OpCode32SimdMovGpElem.Create, OpCode32SimdMovGpElem.CreateT32); // From gen purpose.
|
||||
SetVfp("<<<<1110xxx1xxxxxxxx1011xxx10000", InstName.Vmov, InstEmit32.Vmov_G1, OpCode32SimdMovGpElem.Create, OpCode32SimdMovGpElem.CreateT32); // To gen purpose.
|
||||
SetVfp("<<<<1100010xxxxxxxxx101000x1xxxx", InstName.Vmov, InstEmit32.Vmov_G2, OpCode32SimdMovGpDouble.Create, OpCode32SimdMovGpDouble.CreateT32); // To/from gen purpose x2 and single precision x2.
|
||||
SetVfp("<<<<1100010xxxxxxxxx101100x1xxxx", InstName.Vmov, InstEmit32.Vmov_GD, OpCode32SimdMovGpDouble.Create, OpCode32SimdMovGpDouble.CreateT32); // To/from gen purpose x2 and double precision.
|
||||
SetVfp("<<<<1110000xxxxxxxxx1010x0010000", InstName.Vmov, InstEmit32.Vmov_GS, OpCode32SimdMovGp.Create, OpCode32SimdMovGp.CreateT32); // To/from gen purpose and single precision.
|
||||
SetVfp("<<<<11101x11xxxxxxxx101x0000xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm44.Create, OpCode32SimdImm44.CreateT32); // Scalar f16/32/64 based on size 01 10 11.
|
||||
SetVfp("<<<<11101x110000xxxx101x01x0xxxx", InstName.Vmov, InstEmit32.Vmov_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
SetVfp("<<<<11101111xxxxxxxx101000010000", InstName.Vmrs, InstEmit32.Vmrs, OpCode32SimdSpecial.Create, OpCode32SimdSpecial.CreateT32);
|
||||
SetVfp("<<<<11101110xxxxxxxx101000010000", InstName.Vmsr, InstEmit32.Vmsr, OpCode32SimdSpecial.Create, OpCode32SimdSpecial.CreateT32);
|
||||
SetVfp("<<<<11100x10xxxxxxxx101xx0x0xxxx", InstName.Vmul, InstEmit32.Vmul_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11101x110001xxxx101x01x0xxxx", InstName.Vneg, InstEmit32.Vneg_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
SetVfp("<<<<11100x01xxxxxxxx101xx1x0xxxx", InstName.Vnmla, InstEmit32.Vnmla_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11100x01xxxxxxxx101xx0x0xxxx", InstName.Vnmls, InstEmit32.Vnmls_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("<<<<11100x10xxxxxxxx101xx1x0xxxx", InstName.Vnmul, InstEmit32.Vnmul_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
SetVfp("111111101x1110xxxxxx101x01x0xxxx", InstName.Vrint, InstEmit32.Vrint_RM, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
SetVfp("<<<<11101x110110xxxx101x11x0xxxx", InstName.Vrint, InstEmit32.Vrint_Z, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
SetVfp("<<<<11101x110111xxxx101x01x0xxxx", InstName.Vrintx, InstEmit32.Vrintx_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
SetVfp("<<<<11101x110001xxxx101x11x0xxxx", InstName.Vsqrt, InstEmit32.Vsqrt_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
SetVfp("111111100xxxxxxxxxxx101xx0x0xxxx", InstName.Vsel, InstEmit32.Vsel, OpCode32SimdSel.Create, OpCode32SimdSel.CreateT32);
|
||||
SetVfp("<<<<11001x00xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11001x10xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11010x10xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11001x00xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11001x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<11010x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create, OpCode32SimdMemMult.CreateT32);
|
||||
SetVfp("<<<<1101xx00xxxxxxxx101xxxxxxxxx", InstName.Vstr, InstEmit32.Vstr, OpCode32SimdMemImm.Create, OpCode32SimdMemImm.CreateT32);
|
||||
SetVfp("<<<<11100x11xxxxxxxx101xx1x0xxxx", InstName.Vsub, InstEmit32.Vsub_S, OpCode32SimdRegS.Create, OpCode32SimdRegS.CreateT32);
|
||||
|
||||
// ASIMD
|
||||
SetA32("111100111x110000xxx0001101x0xxx0", InstName.Aesd_V, InstEmit32.Aesd_V, OpCode32Simd.Create);
|
||||
SetA32("111100111x110000xxx0001100x0xxx0", InstName.Aese_V, InstEmit32.Aese_V, OpCode32Simd.Create);
|
||||
SetA32("111100111x110000xxx0001111x0xxx0", InstName.Aesimc_V, InstEmit32.Aesimc_V, OpCode32Simd.Create);
|
||||
@ -803,14 +857,12 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("111100110x10xxx0xxx01100x1x0xxx0", InstName.Sha256su1_V, InstEmit32.Sha256su1_V, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x0x<<xxxxxxxx0111xxx0xxxx", InstName.Vabd, InstEmit32.Vabd_I, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x1x<<xxxxxxxx0111x0x0xxxx", InstName.Vabdl, InstEmit32.Vabdl_I, OpCode32SimdRegLong.Create);
|
||||
SetA32("<<<<11101x110000xxxx101x11x0xxxx", InstName.Vabs, InstEmit32.Vabs_S, OpCode32SimdS.Create);
|
||||
SetA32("111100111x11<<01xxxx00110xx0xxxx", InstName.Vabs, InstEmit32.Vabs_V, OpCode32SimdCmpZ.Create);
|
||||
SetA32("111100111x111001xxxx01110xx0xxxx", InstName.Vabs, InstEmit32.Vabs_V, OpCode32SimdCmpZ.Create);
|
||||
SetA32("111100100xxxxxxxxxxx1000xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_I, OpCode32SimdReg.Create);
|
||||
SetA32("<<<<11100x11xxxxxxxx101xx0x0xxxx", InstName.Vadd, InstEmit32.Vadd_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100100x00xxxxxxxx1101xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_V, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x1x<<xxxxxxxx0000x0x0xxxx", InstName.Vaddl, InstEmit32.Vaddl_I, OpCode32SimdRegLong.Create);
|
||||
SetA32("1111001x1x<<xxxxxxxx0001x0x0xxxx", InstName.Vaddw, InstEmit32.Vaddw_I, OpCode32SimdRegWide.Create);
|
||||
SetA32("1111001x1x<<xxxxxxx00000x0x0xxxx", InstName.Vaddl, InstEmit32.Vaddl_I, OpCode32SimdRegLong.Create);
|
||||
SetA32("1111001x1x<<xxxxxxx00001x0x0xxxx", InstName.Vaddw, InstEmit32.Vaddw_I, OpCode32SimdRegWide.Create);
|
||||
SetA32("111100100x00xxxxxxxx0001xxx1xxxx", InstName.Vand, InstEmit32.Vand_I, OpCode32SimdBinary.Create);
|
||||
SetA32("111100100x01xxxxxxxx0001xxx1xxxx", InstName.Vbic, InstEmit32.Vbic_I, OpCode32SimdBinary.Create);
|
||||
SetA32("1111001x1x000xxxxxxx<<x10x11xxxx", InstName.Vbic, InstEmit32.Vbic_II, OpCode32SimdImm.Create);
|
||||
@ -828,25 +880,13 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("111100111x11xx01xxxx0x000xx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_Z, OpCode32SimdCmpZ.Create);
|
||||
SetA32("111100111x11xx01xxxx0x011xx0xxxx", InstName.Vcle, InstEmit32.Vcle_Z, OpCode32SimdCmpZ.Create);
|
||||
SetA32("111100111x11xx01xxxx0x100xx0xxxx", InstName.Vclt, InstEmit32.Vclt_Z, OpCode32SimdCmpZ.Create);
|
||||
SetA32("<<<<11101x11010xxxxx101x01x0xxxx", InstName.Vcmp, InstEmit32.Vcmp, OpCode32SimdS.Create);
|
||||
SetA32("<<<<11101x11010xxxxx101x11x0xxxx", InstName.Vcmpe, InstEmit32.Vcmpe, OpCode32SimdS.Create);
|
||||
SetA32("111100111x110000xxxx01010xx0xxxx", InstName.Vcnt, InstEmit32.Vcnt, OpCode32SimdCmpZ.Create);
|
||||
SetA32("<<<<11101x110111xxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FD, OpCode32SimdS.Create); // FP 32 and 64, scalar.
|
||||
SetA32("<<<<11101x11110xxxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create); // FP32 to int.
|
||||
SetA32("<<<<11101x111000xxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, OpCode32SimdCvtFI.Create); // Int to FP32.
|
||||
SetA32("111111101x1111xxxxxx101xx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_RM, OpCode32SimdCvtFI.Create); // The many FP32 to int encodings (fp).
|
||||
SetA32("111100111x111011xxxx011xxxx0xxxx", InstName.Vcvt, InstEmit32.Vcvt_V, OpCode32SimdCmpZ.Create); // FP and integer, vector.
|
||||
SetA32("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, OpCode32SimdRegS.Create);
|
||||
SetA32("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, OpCode32SimdDupGP.Create);
|
||||
SetA32("111100111x11xxxxxxxx11000xx0xxxx", InstName.Vdup, InstEmit32.Vdup_1, OpCode32SimdDupElem.Create);
|
||||
SetA32("111100110x00xxxxxxxx0001xxx1xxxx", InstName.Veor, InstEmit32.Veor_I, OpCode32SimdBinary.Create);
|
||||
SetA32("111100101x11xxxxxxxxxxxxxxx0xxxx", InstName.Vext, InstEmit32.Vext, OpCode32SimdExt.Create);
|
||||
SetA32("<<<<11101x10xxxxxxxx101xx0x0xxxx", InstName.Vfma, InstEmit32.Vfma_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100100x00xxxxxxxx1100xxx1xxxx", InstName.Vfma, InstEmit32.Vfma_V, OpCode32SimdReg.Create);
|
||||
SetA32("<<<<11101x10xxxxxxxx101xx1x0xxxx", InstName.Vfms, InstEmit32.Vfms_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100100x10xxxxxxxx1100xxx1xxxx", InstName.Vfms, InstEmit32.Vfms_V, OpCode32SimdReg.Create);
|
||||
SetA32("<<<<11101x01xxxxxxxx101xx1x0xxxx", InstName.Vfnma, InstEmit32.Vfnma_S, OpCode32SimdRegS.Create);
|
||||
SetA32("<<<<11101x01xxxxxxxx101xx0x0xxxx", InstName.Vfnms, InstEmit32.Vfnms_S, OpCode32SimdRegS.Create);
|
||||
SetA32("1111001x0x<<xxxxxxxx0000xxx0xxxx", InstName.Vhadd, InstEmit32.Vhadd, OpCode32SimdReg.Create);
|
||||
SetA32("111101001x10xxxxxxxxxx00xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemSingle.Create);
|
||||
SetA32("111101000x10xxxxxxxx0111xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, OpCode32SimdMemPair.Create); // Regs = 1.
|
||||
@ -860,51 +900,31 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("111101000x10xxxxxxxx010xxxxxxxxx", InstName.Vld3, InstEmit32.Vld3, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
||||
SetA32("111101001x10xxxxxxxxxx11xxxxxxxx", InstName.Vld4, InstEmit32.Vld4, OpCode32SimdMemSingle.Create);
|
||||
SetA32("111101000x10xxxxxxxx000xxxxxxxxx", InstName.Vld4, InstEmit32.Vld4, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
||||
SetA32("<<<<11001x01xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11001x11xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11010x11xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11001x01xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11001x11xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11010x11xxxxxxxx1010xxxxxxxx", InstName.Vldm, InstEmit32.Vldm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<1101xx01xxxxxxxx101xxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, OpCode32SimdMemImm.Create);
|
||||
SetA32("1111001x0x<<xxxxxxxx0110xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_I, OpCode32SimdReg.Create);
|
||||
SetA32("111100100x00xxxxxxxx1111xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_V, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x0x<<xxxxxxxx0110xxx1xxxx", InstName.Vmin, InstEmit32.Vmin_I, OpCode32SimdReg.Create);
|
||||
SetA32("111100100x10xxxxxxxx1111xxx0xxxx", InstName.Vmin, InstEmit32.Vmin_V, OpCode32SimdReg.Create);
|
||||
SetA32("111111101x00xxxxxxxx10>>x0x0xxxx", InstName.Vmaxnm, InstEmit32.Vmaxnm_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100110x0xxxxxxxxx1111xxx1xxxx", InstName.Vmaxnm, InstEmit32.Vmaxnm_V, OpCode32SimdReg.Create);
|
||||
SetA32("111111101x00xxxxxxxx10>>x1x0xxxx", InstName.Vminnm, InstEmit32.Vminnm_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100110x1xxxxxxxxx1111xxx1xxxx", InstName.Vminnm, InstEmit32.Vminnm_V, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x1x<<xxxxxxxx000xx1x0xxxx", InstName.Vmla, InstEmit32.Vmla_1, OpCode32SimdRegElem.Create);
|
||||
SetA32("111100100xxxxxxxxxxx1001xxx0xxxx", InstName.Vmla, InstEmit32.Vmla_I, OpCode32SimdReg.Create);
|
||||
SetA32("<<<<11100x00xxxxxxxx101xx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100100x00xxxxxxxx1101xxx1xxxx", InstName.Vmla, InstEmit32.Vmla_V, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x1x<<xxxxxxx01000x0x0xxxx", InstName.Vmlal, InstEmit32.Vmlal_I, OpCode32SimdRegLong.Create);
|
||||
SetA32("1111001x1x<<xxxxxxxx010xx1x0xxxx", InstName.Vmls, InstEmit32.Vmls_1, OpCode32SimdRegElem.Create);
|
||||
SetA32("<<<<11100x00xxxxxxxx101xx1x0xxxx", InstName.Vmls, InstEmit32.Vmls_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100100x10xxxxxxxx1101xxx1xxxx", InstName.Vmls, InstEmit32.Vmls_V, OpCode32SimdReg.Create);
|
||||
SetA32("111100110xxxxxxxxxxx1001xxx0xxxx", InstName.Vmls, InstEmit32.Vmls_I, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x1x<<xxxxxxx01010x0x0xxxx", InstName.Vmlsl, InstEmit32.Vmlsl_I, OpCode32SimdRegLong.Create);
|
||||
SetA32("<<<<11100xx0xxxxxxxx1011xxx10000", InstName.Vmov, InstEmit32.Vmov_G1, OpCode32SimdMovGpElem.Create); // From gen purpose.
|
||||
SetA32("<<<<1110xxx1xxxxxxxx1011xxx10000", InstName.Vmov, InstEmit32.Vmov_G1, OpCode32SimdMovGpElem.Create); // To gen purpose.
|
||||
SetA32("<<<<1100010xxxxxxxxx101000x1xxxx", InstName.Vmov, InstEmit32.Vmov_G2, OpCode32SimdMovGpDouble.Create); // To/from gen purpose x2 and single precision x2.
|
||||
SetA32("<<<<1100010xxxxxxxxx101100x1xxxx", InstName.Vmov, InstEmit32.Vmov_GD, OpCode32SimdMovGpDouble.Create); // To/from gen purpose x2 and double precision.
|
||||
SetA32("<<<<1110000xxxxxxxxx1010x0010000", InstName.Vmov, InstEmit32.Vmov_GS, OpCode32SimdMovGp.Create); // To/from gen purpose and single precision.
|
||||
SetA32("1111001x1x000xxxxxxx0xx00x01xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q vector I32.
|
||||
SetA32("<<<<11101x11xxxxxxxx101x0000xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm44.Create); // Scalar f16/32/64 based on size 01 10 11.
|
||||
SetA32("1111001x1x000xxxxxxx10x00x01xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q I16.
|
||||
SetA32("1111001x1x000xxxxxxx11xx0x01xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q (dt - from cmode).
|
||||
SetA32("1111001x1x000xxxxxxx11100x11xxxx", InstName.Vmov, InstEmit32.Vmov_I, OpCode32SimdImm.Create); // D/Q I64.
|
||||
SetA32("<<<<11101x110000xxxx101x01x0xxxx", InstName.Vmov, InstEmit32.Vmov_S, OpCode32SimdS.Create);
|
||||
SetA32("1111001x1x001000xxx0101000x1xxxx", InstName.Vmovl, InstEmit32.Vmovl, OpCode32SimdLong.Create);
|
||||
SetA32("1111001x1x010000xxx0101000x1xxxx", InstName.Vmovl, InstEmit32.Vmovl, OpCode32SimdLong.Create);
|
||||
SetA32("1111001x1x100000xxx0101000x1xxxx", InstName.Vmovl, InstEmit32.Vmovl, OpCode32SimdLong.Create);
|
||||
SetA32("111100111x11xx10xxxx001000x0xxx0", InstName.Vmovn, InstEmit32.Vmovn, OpCode32SimdCmpZ.Create);
|
||||
SetA32("<<<<11101111xxxxxxxx101000010000", InstName.Vmrs, InstEmit32.Vmrs, OpCode32SimdSpecial.Create);
|
||||
SetA32("<<<<11101110xxxxxxxx101000010000", InstName.Vmsr, InstEmit32.Vmsr, OpCode32SimdSpecial.Create);
|
||||
SetA32("111100111x11<<10xxxx001000x0xxx0", InstName.Vmovn, InstEmit32.Vmovn, OpCode32SimdMovn.Create);
|
||||
SetA32("1111001x1x<<xxxxxxxx100xx1x0xxxx", InstName.Vmul, InstEmit32.Vmul_1, OpCode32SimdRegElem.Create);
|
||||
SetA32("111100100x<<xxxxxxxx1001xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_I, OpCode32SimdReg.Create);
|
||||
SetA32("111100110x00xxxxxxxx1001xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_I, OpCode32SimdReg.Create);
|
||||
SetA32("<<<<11100x10xxxxxxxx101xx0x0xxxx", InstName.Vmul, InstEmit32.Vmul_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100110x00xxxxxxxx1101xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_V, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x1x<<xxxxxxx01010x1x0xxxx", InstName.Vmull, InstEmit32.Vmull_1, OpCode32SimdRegElemLong.Create);
|
||||
SetA32("1111001x1x<<xxxxxxx01100x0x0xxxx", InstName.Vmull, InstEmit32.Vmull_I, OpCode32SimdRegLong.Create);
|
||||
@ -913,40 +933,46 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("1111001x1x000xxxxxxx0xx00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_II, OpCode32SimdImm.Create); // D/Q vector I32.
|
||||
SetA32("1111001x1x000xxxxxxx10x00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_II, OpCode32SimdImm.Create);
|
||||
SetA32("1111001x1x000xxxxxxx110x0x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_II, OpCode32SimdImm.Create);
|
||||
SetA32("<<<<11101x110001xxxx101x01x0xxxx", InstName.Vneg, InstEmit32.Vneg_S, OpCode32SimdS.Create);
|
||||
SetA32("111100111x11<<01xxxx00111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, OpCode32SimdCmpZ.Create);
|
||||
SetA32("111100111x111001xxxx01111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, OpCode32SimdCmpZ.Create);
|
||||
SetA32("<<<<11100x01xxxxxxxx101xx1x0xxxx", InstName.Vnmla, InstEmit32.Vnmla_S, OpCode32SimdRegS.Create);
|
||||
SetA32("<<<<11100x01xxxxxxxx101xx0x0xxxx", InstName.Vnmls, InstEmit32.Vnmls_S, OpCode32SimdRegS.Create);
|
||||
SetA32("<<<<11100x10xxxxxxxx101xx1x0xxxx", InstName.Vnmul, InstEmit32.Vnmul_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100100x11xxxxxxxx0001xxx1xxxx", InstName.Vorn, InstEmit32.Vorn_I, OpCode32SimdBinary.Create);
|
||||
SetA32("111100100x10xxxxxxxx0001xxx1xxxx", InstName.Vorr, InstEmit32.Vorr_I, OpCode32SimdBinary.Create);
|
||||
SetA32("1111001x1x000xxxxxxx<<x10x01xxxx", InstName.Vorr, InstEmit32.Vorr_II, OpCode32SimdImm.Create);
|
||||
SetA32("111100100x<<xxxxxxxx1011x0x1xxxx", InstName.Vpadd, InstEmit32.Vpadd_I, OpCode32SimdReg.Create);
|
||||
SetA32("111100110x00xxxxxxxx1101x0x0xxxx", InstName.Vpadd, InstEmit32.Vpadd_V, OpCode32SimdReg.Create);
|
||||
SetA32("111100111x11<<00xxxx0010xxx0xxxx", InstName.Vpaddl, InstEmit32.Vpaddl, OpCode32SimdCmpZ.Create);
|
||||
SetA32("1111001x0x<<xxxxxxxx1010x0x0xxxx", InstName.Vpmax, InstEmit32.Vpmax_I, OpCode32SimdReg.Create);
|
||||
SetA32("111100110x00xxxxxxxx1111x0x0xxxx", InstName.Vpmax, InstEmit32.Vpmax_V, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x0x<<xxxxxxxx1010x0x1xxxx", InstName.Vpmin, InstEmit32.Vpmin_I, OpCode32SimdReg.Create);
|
||||
SetA32("111100110x10xxxxxxxx1111x0x0xxxx", InstName.Vpmin, InstEmit32.Vpmin_V, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x0xxxxxxxxxxx0000xxx1xxxx", InstName.Vqadd, InstEmit32.Vqadd, OpCode32SimdReg.Create);
|
||||
SetA32("111100100x01xxxxxxxx1011xxx0xxxx", InstName.Vqdmulh, InstEmit32.Vqdmulh, OpCode32SimdReg.Create);
|
||||
SetA32("111100100x10xxxxxxxx1011xxx0xxxx", InstName.Vqdmulh, InstEmit32.Vqdmulh, OpCode32SimdReg.Create);
|
||||
SetA32("111100111x11<<10xxxx00101xx0xxx0", InstName.Vqmovn, InstEmit32.Vqmovn, OpCode32SimdMovn.Create);
|
||||
SetA32("111100111x11<<10xxxx001001x0xxx0", InstName.Vqmovun, InstEmit32.Vqmovun, OpCode32SimdMovn.Create);
|
||||
SetA32("1111001x1x>>>xxxxxxx100101x1xxx0", InstName.Vqrshrn, InstEmit32.Vqrshrn, OpCode32SimdShImmNarrow.Create);
|
||||
SetA32("111100111x>>>xxxxxxx100001x1xxx0", InstName.Vqrshrun, InstEmit32.Vqrshrun, OpCode32SimdShImmNarrow.Create);
|
||||
SetA32("1111001x1x>>>xxxxxxx100100x1xxx0", InstName.Vqshrn, InstEmit32.Vqshrn, OpCode32SimdShImmNarrow.Create);
|
||||
SetA32("111100111x>>>xxxxxxx100000x1xxx0", InstName.Vqshrun, InstEmit32.Vqshrun, OpCode32SimdShImmNarrow.Create);
|
||||
SetA32("1111001x0xxxxxxxxxxx0010xxx1xxxx", InstName.Vqsub, InstEmit32.Vqsub, OpCode32SimdReg.Create);
|
||||
SetA32("111100111x111011xxxx010x0xx0xxxx", InstName.Vrecpe, InstEmit32.Vrecpe, OpCode32SimdSqrte.Create);
|
||||
SetA32("111100100x00xxxxxxxx1111xxx1xxxx", InstName.Vrecps, InstEmit32.Vrecps, OpCode32SimdReg.Create);
|
||||
SetA32("111100111x11xx00xxxx000<<xx0xxxx", InstName.Vrev, InstEmit32.Vrev, OpCode32SimdRev.Create);
|
||||
SetA32("111111101x1110xxxxxx101x01x0xxxx", InstName.Vrint, InstEmit32.Vrint_RM, OpCode32SimdS.Create);
|
||||
SetA32("<<<<11101x110110xxxx101x11x0xxxx", InstName.Vrint, InstEmit32.Vrint_Z, OpCode32SimdS.Create);
|
||||
SetA32("<<<<11101x110111xxxx101x01x0xxxx", InstName.Vrintx, InstEmit32.Vrintx_S, OpCode32SimdS.Create);
|
||||
SetA32("1111001x0x<<xxxxxxxx0001xxx0xxxx", InstName.Vrhadd, InstEmit32.Vrhadd, OpCode32SimdReg.Create);
|
||||
SetA32("111100111x111010xxxx01010xx0xxxx", InstName.Vrinta, InstEmit32.Vrinta_V, OpCode32SimdCmpZ.Create);
|
||||
SetA32("111100111x111010xxxx01101xx0xxxx", InstName.Vrintm, InstEmit32.Vrintm_V, OpCode32SimdCmpZ.Create);
|
||||
SetA32("111100111x111010xxxx01000xx0xxxx", InstName.Vrintn, InstEmit32.Vrintn_V, OpCode32SimdCmpZ.Create);
|
||||
SetA32("111100111x111010xxxx01111xx0xxxx", InstName.Vrintp, InstEmit32.Vrintp_V, OpCode32SimdCmpZ.Create);
|
||||
SetA32("1111001x1x>>>xxxxxxx0010>xx1xxxx", InstName.Vrshr, InstEmit32.Vrshr, OpCode32SimdShImm.Create);
|
||||
SetA32("111100101x>>>xxxxxxx100001x1xxx0", InstName.Vrshrn, InstEmit32.Vrshrn, OpCode32SimdShImmNarrow.Create);
|
||||
SetA32("111100111x111011xxxx010x1xx0xxxx", InstName.Vrsqrte, InstEmit32.Vrsqrte, OpCode32SimdSqrte.Create);
|
||||
SetA32("111100100x10xxxxxxxx1111xxx1xxxx", InstName.Vrsqrts, InstEmit32.Vrsqrts, OpCode32SimdReg.Create);
|
||||
SetA32("111111100xxxxxxxxxxx101xx0x0xxxx", InstName.Vsel, InstEmit32.Vsel, OpCode32SimdSel.Create);
|
||||
SetA32("1111001x1x>>>xxxxxxx0011>xx1xxxx", InstName.Vrsra, InstEmit32.Vrsra, OpCode32SimdShImm.Create);
|
||||
SetA32("111100101x>>>xxxxxxx0101>xx1xxxx", InstName.Vshl, InstEmit32.Vshl, OpCode32SimdShImm.Create);
|
||||
SetA32("1111001x0xxxxxxxxxxx0100xxx0xxxx", InstName.Vshl, InstEmit32.Vshl_I, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x1x>>>xxxxxxx101000x1xxxx", InstName.Vshll, InstEmit32.Vshll, OpCode32SimdShImmLong.Create); // A1 encoding.
|
||||
SetA32("1111001x1x>>>xxxxxxx0000>xx1xxxx", InstName.Vshr, InstEmit32.Vshr, OpCode32SimdShImm.Create);
|
||||
SetA32("111100101x>>>xxxxxxx100000x1xxx0", InstName.Vshrn, InstEmit32.Vshrn, OpCode32SimdShImmNarrow.Create);
|
||||
SetA32("<<<<11101x110001xxxx101x11x0xxxx", InstName.Vsqrt, InstEmit32.Vsqrt_S, OpCode32SimdS.Create);
|
||||
SetA32("1111001x1x>>>xxxxxxx0001>xx1xxxx", InstName.Vsra, InstEmit32.Vsra, OpCode32SimdShImm.Create);
|
||||
SetA32("111101001x00xxxxxxxx<<00xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemSingle.Create);
|
||||
SetA32("111101000x00xxxxxxxx0111xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, OpCode32SimdMemPair.Create); // Regs = 1.
|
||||
@ -960,17 +986,10 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("111101000x00xxxxxxxx010xxxxxxxxx", InstName.Vst3, InstEmit32.Vst3, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
||||
SetA32("111101001x00xxxxxxxx<<11xxxxxxxx", InstName.Vst4, InstEmit32.Vst4, OpCode32SimdMemSingle.Create);
|
||||
SetA32("111101000x00xxxxxxxx000xxxxxxxxx", InstName.Vst4, InstEmit32.Vst4, OpCode32SimdMemPair.Create); // Inc = 1/2 (itype).
|
||||
SetA32("<<<<11001x00xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11001x10xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11010x10xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11001x00xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11001x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<11010x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, OpCode32SimdMemMult.Create);
|
||||
SetA32("<<<<1101xx00xxxxxxxx101xxxxxxxxx", InstName.Vstr, InstEmit32.Vstr, OpCode32SimdMemImm.Create);
|
||||
SetA32("111100110xxxxxxxxxxx1000xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_I, OpCode32SimdReg.Create);
|
||||
SetA32("<<<<11100x11xxxxxxxx101xx1x0xxxx", InstName.Vsub, InstEmit32.Vsub_S, OpCode32SimdRegS.Create);
|
||||
SetA32("111100100x10xxxxxxxx1101xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_V, OpCode32SimdReg.Create);
|
||||
SetA32("1111001x1x<<xxxxxxxx0011x0x0xxxx", InstName.Vsubw, InstEmit32.Vsubw_I, OpCode32SimdRegWide.Create);
|
||||
SetA32("1111001x1x<<xxxxxxx00010x0x0xxxx", InstName.Vsubl, InstEmit32.Vsubl_I, OpCode32SimdRegLong.Create);
|
||||
SetA32("1111001x1x<<xxxxxxx00011x0x0xxxx", InstName.Vsubw, InstEmit32.Vsubw_I, OpCode32SimdRegWide.Create);
|
||||
SetA32("111100111x11xxxxxxxx10xxxxx0xxxx", InstName.Vtbl, InstEmit32.Vtbl, OpCode32SimdTbl.Create);
|
||||
SetA32("111100111x11<<10xxxx00001xx0xxxx", InstName.Vtrn, InstEmit32.Vtrn, OpCode32SimdCmpZ.Create);
|
||||
SetA32("111100100x<<xxxxxxxx1000xxx1xxxx", InstName.Vtst, InstEmit32.Vtst, OpCode32SimdReg.Create);
|
||||
@ -1008,7 +1027,7 @@ namespace ARMeilleure.Decoders
|
||||
SetT16("01000101xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT16AluRegHigh.Create);
|
||||
SetT16("01000110xxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16AluRegHigh.Create);
|
||||
SetT16("010001110xxxx000", InstName.Bx, InstEmit32.Bx, OpCodeT16BReg.Create);
|
||||
SetT16("010001111xxxx000", InstName.Blx, InstEmit32.Blx, OpCodeT16BReg.Create);
|
||||
SetT16("010001111xxxx000", InstName.Blx, InstEmit32.Blxr, OpCodeT16BReg.Create);
|
||||
SetT16("01001xxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT16MemLit.Create);
|
||||
SetT16("0101000xxxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT16MemReg.Create);
|
||||
SetT16("0101001xxxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT16MemReg.Create);
|
||||
@ -1056,49 +1075,71 @@ namespace ARMeilleure.Decoders
|
||||
SetT32("11110x01010xxxxx0xxxxxxxxxxxxxxx", InstName.Adc, InstEmit32.Adc, OpCodeT32AluImm.Create);
|
||||
SetT32("11101011000<xxxx0xxx<<<<xxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x01000<xxxx0xxx<<<<xxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT32AluImm.Create);
|
||||
SetT32("11110x100000xxxx0xxxxxxxxxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT32AluImm12.Create);
|
||||
SetT32("11101010000<xxxx0xxx<<<<xxxxxxxx", InstName.And, InstEmit32.And, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x00000<xxxx0xxx<<<<xxxxxxxx", InstName.And, InstEmit32.And, OpCodeT32AluImm.Create);
|
||||
SetT32("11110x<<<xxxxxxx10x0xxxxxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT32BImm20.Create);
|
||||
SetT32("11110xxxxxxxxxxx10x1xxxxxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT32BImm24.Create);
|
||||
SetT32("11110011011011110xxxxxxxxx0xxxxx", InstName.Bfc, InstEmit32.Bfc, OpCodeT32AluBf.Create);
|
||||
SetT32("111100110110<<<<0xxxxxxxxx0xxxxx", InstName.Bfi, InstEmit32.Bfi, OpCodeT32AluBf.Create);
|
||||
SetT32("11101010001xxxxx0xxxxxxxxxxxxxxx", InstName.Bic, InstEmit32.Bic, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x00001xxxxx0xxxxxxxxxxxxxxx", InstName.Bic, InstEmit32.Bic, OpCodeT32AluImm.Create);
|
||||
SetT32("11110xxxxxxxxxxx11x1xxxxxxxxxxxx", InstName.Bl, InstEmit32.Bl, OpCodeT32BImm24.Create);
|
||||
SetT32("11110xxxxxxxxxxx11x0xxxxxxxxxxx0", InstName.Blx, InstEmit32.Blx, OpCodeT32BImm24.Create);
|
||||
SetT32("111110101011xxxx1111xxxx1000xxxx", InstName.Clz, InstEmit32.Clz, OpCodeT32AluReg.Create);
|
||||
SetT32("111010110001xxxx0xxx1111xxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x010001xxxx0xxx1111xxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCodeT32AluImm.Create);
|
||||
SetT32("111010111011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x011011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluImm.Create);
|
||||
SetT32("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x00100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluImm.Create);
|
||||
SetT32("111010001101xxxxxxxx111110101111", InstName.Lda, InstEmit32.Lda, OpCodeT32MemLdEx.Create);
|
||||
SetT32("111010001101xxxxxxxx111110001111", InstName.Ldab, InstEmit32.Ldab, OpCodeT32MemLdEx.Create);
|
||||
SetT32("111010001101xxxxxxxx111111101111", InstName.Ldaex, InstEmit32.Ldaex, OpCodeT32MemLdEx.Create);
|
||||
SetT32("111010001101xxxxxxxx111111001111", InstName.Ldaexb, InstEmit32.Ldaexb, OpCodeT32MemLdEx.Create);
|
||||
SetT32("111010001101xxxxxxxxxxxx11111111", InstName.Ldaexd, InstEmit32.Ldaexd, OpCodeT32MemLdEx.Create);
|
||||
SetT32("111010001101xxxxxxxx111111011111", InstName.Ldaexh, InstEmit32.Ldaexh, OpCodeT32MemLdEx.Create);
|
||||
SetT32("111010001101xxxxxxxx111110011111", InstName.Ldah, InstEmit32.Ldah, OpCodeT32MemLdEx.Create);
|
||||
SetT32("1110100010x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT32MemMult.Create);
|
||||
SetT32("1110100100x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT32MemMult.Create);
|
||||
SetT32("111110000101xxxx<<<<10x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000101xxxx<<<<1100xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000101xxxx<<<<11x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000101xxxxxxxx10x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000101xxxxxxxx1100xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000101xxxxxxxx11x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110001101xxxxxxxxxxxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm12.Create);
|
||||
SetT32("111110000101<<<<xxxx000000xxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemRsImm.Create);
|
||||
SetT32("111110000001xxxx<<<<10x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000001xxxx<<<<1100xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000001xxxx<<<<11x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000001xxxxxxxx10x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000001xxxxxxxx1100xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000001xxxxxxxx11x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110001001xxxxxxxxxxxxxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm12.Create);
|
||||
SetT32("1110100>x1>1<<<<xxxxxxxxxxxxxxxx", InstName.Ldrd, InstEmit32.Ldrd, OpCodeT32MemImm8D.Create);
|
||||
SetT32("111110000011xxxx<<<<10x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000011xxxx<<<<1100xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000011xxxx<<<<11x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000001xxxx<<<<000000xxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemRsImm.Create);
|
||||
SetT32("11101000x111<<<<xxxxxxxxxxxxxxxx", InstName.Ldrd, InstEmit32.Ldrd, OpCodeT32MemImm8D.Create);
|
||||
SetT32("11101001x1x1<<<<xxxxxxxxxxxxxxxx", InstName.Ldrd, InstEmit32.Ldrd, OpCodeT32MemImm8D.Create);
|
||||
SetT32("111110000011xxxxxxxx10x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000011xxxxxxxx1100xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000011xxxxxxxx11x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110001011xxxxxxxxxxxxxxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm12.Create);
|
||||
SetT32("111110010001xxxx<<<<10x1xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110010001xxxx<<<<1100xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110010001xxxx<<<<11x1xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110000011xxxx<<<<000000xxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemRsImm.Create);
|
||||
SetT32("111110010001xxxxxxxx10x1xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110010001xxxxxxxx1100xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110010001xxxxxxxx11x1xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110011001xxxxxxxxxxxxxxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm12.Create);
|
||||
SetT32("111110010011xxxx<<<<10x1xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110010011xxxx<<<<1100xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110010011xxxx<<<<11x1xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110010001xxxx<<<<000000xxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemRsImm.Create);
|
||||
SetT32("111110010011xxxxxxxx10x1xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110010011xxxxxxxx1100xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110010011xxxxxxxx11x1xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110011011xxxxxxxxxxxxxxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm12.Create);
|
||||
SetT32("111110010011xxxx<<<<000000xxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemRsImm.Create);
|
||||
SetT32("111110110000xxxx<<<<xxxx0000xxxx", InstName.Mla, InstEmit32.Mla, OpCodeT32AluMla.Create);
|
||||
SetT32("111110110000xxxxxxxxxxxx0001xxxx", InstName.Mls, InstEmit32.Mls, OpCodeT32AluMla.Create);
|
||||
SetT32("11101010010x11110xxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32AluRsImm.Create);
|
||||
SetT32("111110100xxxxxxx1111xxxx0000xxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32ShiftReg.Create);
|
||||
SetT32("11110x00010x11110xxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32AluImm.Create);
|
||||
SetT32("11110x100100xxxx0xxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32MovImm16.Create);
|
||||
SetT32("11110x101100xxxx0xxxxxxxxxxxxxxx", InstName.Movt, InstEmit32.Movt, OpCodeT32MovImm16.Create);
|
||||
SetT32("111110110000xxxx1111xxxx0000xxxx", InstName.Mul, InstEmit32.Mul, OpCodeT32AluMla.Create);
|
||||
SetT32("11101010011x11110xxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x00011x11110xxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCodeT32AluImm.Create);
|
||||
SetT32("11110011101011111000000000000000", InstName.Nop, InstEmit32.Nop, OpCodeT32.Create);
|
||||
SetT32("11101010011x<<<<0xxxxxxxxxxxxxxx", InstName.Orn, InstEmit32.Orn, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x00011x<<<<0xxxxxxxxxxxxxxx", InstName.Orn, InstEmit32.Orn, OpCodeT32AluImm.Create);
|
||||
SetT32("11101010010x<<<<0xxxxxxxxxxxxxxx", InstName.Orr, InstEmit32.Orr, OpCodeT32AluRsImm.Create);
|
||||
@ -1107,7 +1148,24 @@ namespace ARMeilleure.Decoders
|
||||
SetT32("11110x01110xxxxx0xxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, OpCodeT32AluImm.Create);
|
||||
SetT32("11101011011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x01011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluImm.Create);
|
||||
SetT32("111100110100xxxx0xxxxxxxxx0xxxxx", InstName.Sbfx, InstEmit32.Sbfx, OpCodeT32AluBf.Create);
|
||||
SetT32("111110111001xxxx1111xxxx1111xxxx", InstName.Sdiv, InstEmit32.Sdiv, OpCodeT32AluMla.Create);
|
||||
SetT32("111110110001xxxx<<<<xxxx00xxxxxx", InstName.Smla__, InstEmit32.Smla__, OpCodeT32AluMla.Create);
|
||||
SetT32("111110111100xxxxxxxxxxxx0000xxxx", InstName.Smlal, InstEmit32.Smlal, OpCodeT32AluUmull.Create);
|
||||
SetT32("111110111100xxxxxxxxxxxx10xxxxxx", InstName.Smlal__, InstEmit32.Smlal__, OpCodeT32AluUmull.Create);
|
||||
SetT32("111110110011xxxx<<<<xxxx000xxxxx", InstName.Smlaw_, InstEmit32.Smlaw_, OpCodeT32AluMla.Create);
|
||||
SetT32("111110110101xxxx<<<<xxxx000xxxxx", InstName.Smmla, InstEmit32.Smmla, OpCodeT32AluMla.Create);
|
||||
SetT32("111110110110xxxxxxxxxxxx000xxxxx", InstName.Smmls, InstEmit32.Smmls, OpCodeT32AluMla.Create);
|
||||
SetT32("111110110001xxxx1111xxxx00xxxxxx", InstName.Smul__, InstEmit32.Smul__, OpCodeT32AluMla.Create);
|
||||
SetT32("111110111000xxxxxxxxxxxx0000xxxx", InstName.Smull, InstEmit32.Smull, OpCodeT32AluUmull.Create);
|
||||
SetT32("111110110011xxxx1111xxxx000xxxxx", InstName.Smulw_, InstEmit32.Smulw_, OpCodeT32AluMla.Create);
|
||||
SetT32("111010001100xxxxxxxx111110101111", InstName.Stl, InstEmit32.Stl, OpCodeT32MemStEx.Create);
|
||||
SetT32("111010001100xxxxxxxx111110001111", InstName.Stlb, InstEmit32.Stlb, OpCodeT32MemStEx.Create);
|
||||
SetT32("111010001100xxxxxxxx11111110xxxx", InstName.Stlex, InstEmit32.Stlex, OpCodeT32MemStEx.Create);
|
||||
SetT32("111010001100xxxxxxxx11111100xxxx", InstName.Stlexb, InstEmit32.Stlexb, OpCodeT32MemStEx.Create);
|
||||
SetT32("111010001100xxxxxxxxxxxx1111xxxx", InstName.Stlexd, InstEmit32.Stlexd, OpCodeT32MemStEx.Create);
|
||||
SetT32("111010001100xxxxxxxx11111101xxxx", InstName.Stlexh, InstEmit32.Stlexh, OpCodeT32MemStEx.Create);
|
||||
SetT32("111010001100xxxxxxxx111110011111", InstName.Stlh, InstEmit32.Stlh, OpCodeT32MemStEx.Create);
|
||||
SetT32("1110100010x0xxxx0xxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT32MemMult.Create);
|
||||
SetT32("1110100100x0xxxx0xxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT32MemMult.Create);
|
||||
SetT32("111110000100xxxxxxxx1<<>xxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemImm8.Create);
|
||||
@ -1115,15 +1173,31 @@ namespace ARMeilleure.Decoders
|
||||
SetT32("111110000100<<<<xxxx000000xxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemRsImm.Create);
|
||||
SetT32("111110000000xxxxxxxx1<<>xxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110001000xxxxxxxxxxxxxxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm12.Create);
|
||||
SetT32("1110100>x1>0<<<<xxxxxxxxxxxxxxxx", InstName.Strd, InstEmit32.Strd, OpCodeT32MemImm8D.Create);
|
||||
SetT32("111110000000<<<<xxxx000000xxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemRsImm.Create);
|
||||
SetT32("11101000x110<<<<xxxxxxxxxxxxxxxx", InstName.Strd, InstEmit32.Strd, OpCodeT32MemImm8D.Create);
|
||||
SetT32("11101001x1x0<<<<xxxxxxxxxxxxxxxx", InstName.Strd, InstEmit32.Strd, OpCodeT32MemImm8D.Create);
|
||||
SetT32("111110000010xxxxxxxx1<<>xxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm8.Create);
|
||||
SetT32("111110001010xxxxxxxxxxxxxxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm12.Create);
|
||||
SetT32("111110000010<<<<xxxx000000xxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemRsImm.Create);
|
||||
SetT32("11101011101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x01101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluImm.Create);
|
||||
SetT32("111110100100xxxx1111xxxx10xxxxxx", InstName.Sxtb, InstEmit32.Sxtb, OpCodeT32AluUx.Create);
|
||||
SetT32("111110100010xxxx1111xxxx10xxxxxx", InstName.Sxtb16, InstEmit32.Sxtb16, OpCodeT32AluUx.Create);
|
||||
SetT32("111110100000xxxx1111xxxx10xxxxxx", InstName.Sxth, InstEmit32.Sxth, OpCodeT32AluUx.Create);
|
||||
SetT32("111010001101xxxx111100000000xxxx", InstName.Tbb, InstEmit32.Tbb, OpCodeT32Tb.Create);
|
||||
SetT32("111010001101xxxx111100000001xxxx", InstName.Tbh, InstEmit32.Tbh, OpCodeT32Tb.Create);
|
||||
SetT32("111010101001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x001001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluImm.Create);
|
||||
SetT32("111010100001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x000001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluImm.Create);
|
||||
SetT32("111100111100xxxx0xxxxxxxxx0xxxxx", InstName.Ubfx, InstEmit32.Ubfx, OpCodeT32AluBf.Create);
|
||||
SetT32("111110111011xxxx1111xxxx1111xxxx", InstName.Udiv, InstEmit32.Udiv, OpCodeT32AluMla.Create);
|
||||
SetT32("111110111110xxxxxxxxxxxx0110xxxx", InstName.Umaal, InstEmit32.Umaal, OpCodeT32AluUmull.Create);
|
||||
SetT32("111110111110xxxxxxxxxxxx0000xxxx", InstName.Umlal, InstEmit32.Umlal, OpCodeT32AluUmull.Create);
|
||||
SetT32("111110111010xxxxxxxxxxxx0000xxxx", InstName.Umull, InstEmit32.Umull, OpCodeT32AluUmull.Create);
|
||||
SetT32("111110100101xxxx1111xxxx10xxxxxx", InstName.Uxtb, InstEmit32.Uxtb, OpCodeT32AluUx.Create);
|
||||
SetT32("111110100011xxxx1111xxxx10xxxxxx", InstName.Uxtb16, InstEmit32.Uxtb16, OpCodeT32AluUx.Create);
|
||||
SetT32("111110100001xxxx1111xxxx10xxxxxx", InstName.Uxth, InstEmit32.Uxth, OpCodeT32AluUx.Create);
|
||||
#endregion
|
||||
|
||||
FillFastLookupTable(InstA32FastLookup, AllInstA32, ToFastLookupIndexA);
|
||||
@ -1180,6 +1254,18 @@ namespace ARMeilleure.Decoders
|
||||
Set(reversedEncoding, AllInstT32, new InstDescriptor(name, emitter), reversedMakeOp);
|
||||
}
|
||||
|
||||
private static void SetVfp(string encoding, InstName name, InstEmitter emitter, MakeOp makeOpA32, MakeOp makeOpT32)
|
||||
{
|
||||
SetA32(encoding, name, emitter, makeOpA32);
|
||||
|
||||
string thumbEncoding = encoding;
|
||||
if (thumbEncoding.StartsWith("<<<<"))
|
||||
{
|
||||
thumbEncoding = "1110" + thumbEncoding.Substring(4);
|
||||
}
|
||||
SetT32(thumbEncoding, name, emitter, makeOpT32);
|
||||
}
|
||||
|
||||
private static void SetA64(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
|
||||
{
|
||||
Set(encoding, AllInstA64, new InstDescriptor(name, emitter), makeOp);
|
||||
|
@ -1,51 +0,0 @@
|
||||
using System.Diagnostics.Tracing;
|
||||
|
||||
namespace ARMeilleure.Diagnostics.EventSources
|
||||
{
|
||||
[EventSource(Name = "ARMeilleure")]
|
||||
class AddressTableEventSource : EventSource
|
||||
{
|
||||
public static readonly AddressTableEventSource Log = new();
|
||||
|
||||
private ulong _size;
|
||||
private ulong _leafSize;
|
||||
private PollingCounter _sizeCounter;
|
||||
private PollingCounter _leafSizeCounter;
|
||||
|
||||
public AddressTableEventSource()
|
||||
{
|
||||
_sizeCounter = new PollingCounter("addr-tab-alloc", this, () => _size / 1024d / 1024d)
|
||||
{
|
||||
DisplayName = "AddressTable Total Bytes Allocated",
|
||||
DisplayUnits = "MB"
|
||||
};
|
||||
|
||||
_leafSizeCounter = new PollingCounter("addr-tab-leaf-alloc", this, () => _leafSize / 1024d / 1024d)
|
||||
{
|
||||
DisplayName = "AddressTable Total Leaf Bytes Allocated",
|
||||
DisplayUnits = "MB"
|
||||
};
|
||||
}
|
||||
|
||||
public void Allocated(int bytes, bool leaf)
|
||||
{
|
||||
_size += (uint)bytes;
|
||||
|
||||
if (leaf)
|
||||
{
|
||||
_leafSize += (uint)bytes;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_leafSizeCounter.Dispose();
|
||||
_leafSizeCounter = null;
|
||||
|
||||
_sizeCounter.Dispose();
|
||||
_sizeCounter = null;
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
67
ARMeilleure/Diagnostics/TranslatorEventSource.cs
Normal file
67
ARMeilleure/Diagnostics/TranslatorEventSource.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Threading;
|
||||
|
||||
namespace ARMeilleure.Diagnostics
|
||||
{
|
||||
[EventSource(Name = "ARMeilleure")]
|
||||
class TranslatorEventSource : EventSource
|
||||
{
|
||||
public static readonly TranslatorEventSource Log = new();
|
||||
|
||||
private int _rejitQueue;
|
||||
private ulong _funcTabSize;
|
||||
private ulong _funcTabLeafSize;
|
||||
private PollingCounter _rejitQueueCounter;
|
||||
private PollingCounter _funcTabSizeCounter;
|
||||
private PollingCounter _funcTabLeafSizeCounter;
|
||||
|
||||
public TranslatorEventSource()
|
||||
{
|
||||
_rejitQueueCounter = new PollingCounter("rejit-queue-length", this, () => _rejitQueue)
|
||||
{
|
||||
DisplayName = "Rejit Queue Length"
|
||||
};
|
||||
|
||||
_funcTabSizeCounter = new PollingCounter("addr-tab-alloc", this, () => _funcTabSize / 1024d / 1024d)
|
||||
{
|
||||
DisplayName = "AddressTable Total Bytes Allocated",
|
||||
DisplayUnits = "MB"
|
||||
};
|
||||
|
||||
_funcTabLeafSizeCounter = new PollingCounter("addr-tab-leaf-alloc", this, () => _funcTabLeafSize / 1024d / 1024d)
|
||||
{
|
||||
DisplayName = "AddressTable Total Leaf Bytes Allocated",
|
||||
DisplayUnits = "MB"
|
||||
};
|
||||
}
|
||||
|
||||
public void RejitQueueAdd(int count)
|
||||
{
|
||||
Interlocked.Add(ref _rejitQueue, count);
|
||||
}
|
||||
|
||||
public void AddressTableAllocated(int bytes, bool leaf)
|
||||
{
|
||||
_funcTabSize += (uint)bytes;
|
||||
|
||||
if (leaf)
|
||||
{
|
||||
_funcTabLeafSize += (uint)bytes;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_rejitQueueCounter.Dispose();
|
||||
_rejitQueueCounter = null;
|
||||
|
||||
_funcTabLeafSizeCounter.Dispose();
|
||||
_funcTabLeafSizeCounter = null;
|
||||
|
||||
_funcTabSizeCounter.Dispose();
|
||||
_funcTabSizeCounter = null;
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
@ -74,7 +74,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Bfc(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluBf op = (OpCode32AluBf)context.CurrOp;
|
||||
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
||||
|
||||
Operand d = GetIntA32(context, op.Rd);
|
||||
Operand res = context.BitwiseAnd(d, Const(~op.DestMask));
|
||||
@ -84,7 +84,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Bfi(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluBf op = (OpCode32AluBf)context.CurrOp;
|
||||
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
||||
|
||||
Operand n = GetIntA32(context, op.Rn);
|
||||
Operand d = GetIntA32(context, op.Rd);
|
||||
@ -185,7 +185,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Movt(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluImm16 op = (OpCode32AluImm16)context.CurrOp;
|
||||
IOpCode32AluImm16 op = (IOpCode32AluImm16)context.CurrOp;
|
||||
|
||||
Operand d = GetIntA32(context, op.Rd);
|
||||
Operand imm = Const(op.Immediate << 16); // Immeditate value as top halfword.
|
||||
@ -389,7 +389,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Sbfx(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluBf op = (OpCode32AluBf)context.CurrOp;
|
||||
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
||||
|
||||
var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
||||
|
||||
@ -484,7 +484,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Ubfx(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluBf op = (OpCode32AluBf)context.CurrOp;
|
||||
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
|
||||
|
||||
var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
|
||||
|
||||
|
@ -128,7 +128,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
Debug.Assert(value.Type == OperandType.I32);
|
||||
|
||||
if (((OpCode32)context.CurrOp).IsThumb())
|
||||
if (((OpCode32)context.CurrOp).IsThumb)
|
||||
{
|
||||
bool isReturn = IsA32Return(context);
|
||||
if (!isReturn)
|
||||
@ -205,7 +205,7 @@ namespace ARMeilleure.Instructions
|
||||
return Const(op.Immediate);
|
||||
}
|
||||
|
||||
case OpCode32AluImm16 op: return Const(op.Immediate);
|
||||
case IOpCode32AluImm16 op: return Const(op.Immediate);
|
||||
|
||||
case IOpCode32AluRsImm op: return GetMShiftedByImmediate(context, op, setCarry);
|
||||
case IOpCode32AluRsReg op: return GetMShiftedByReg(context, op, setCarry);
|
||||
|
@ -34,7 +34,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
uint pc = op.GetPc();
|
||||
|
||||
bool isThumb = ((OpCode32)context.CurrOp).IsThumb();
|
||||
bool isThumb = ((OpCode32)context.CurrOp).IsThumb;
|
||||
|
||||
uint currentPc = isThumb
|
||||
? pc | 1
|
||||
@ -61,7 +61,7 @@ namespace ARMeilleure.Instructions
|
||||
Operand addr = context.Copy(GetIntA32(context, op.Rm));
|
||||
Operand bitOne = context.BitwiseAnd(addr, Const(1));
|
||||
|
||||
bool isThumb = ((OpCode32)context.CurrOp).IsThumb();
|
||||
bool isThumb = ((OpCode32)context.CurrOp).IsThumb;
|
||||
|
||||
uint currentPc = isThumb
|
||||
? (pc - 2) | 1
|
||||
@ -107,5 +107,30 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
context.SetIfThenBlockState(op.IfThenBlockConds);
|
||||
}
|
||||
|
||||
public static void Tbb(ArmEmitterContext context) => EmitTb(context, halfword: false);
|
||||
public static void Tbh(ArmEmitterContext context) => EmitTb(context, halfword: true);
|
||||
|
||||
private static void EmitTb(ArmEmitterContext context, bool halfword)
|
||||
{
|
||||
OpCodeT32Tb op = (OpCodeT32Tb)context.CurrOp;
|
||||
|
||||
Operand halfwords;
|
||||
|
||||
if (halfword)
|
||||
{
|
||||
Operand address = context.Add(GetIntA32(context, op.Rn), context.ShiftLeft(GetIntA32(context, op.Rm), Const(1)));
|
||||
halfwords = InstEmitMemoryHelper.EmitReadInt(context, address, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Operand address = context.Add(GetIntA32(context, op.Rn), GetIntA32(context, op.Rm));
|
||||
halfwords = InstEmitMemoryHelper.EmitReadIntAligned(context, address, 0);
|
||||
}
|
||||
|
||||
Operand targetAddress = context.Add(Const((int)op.GetPc()), context.ShiftLeft(halfwords, Const(1)));
|
||||
|
||||
EmitVirtualJump(context, targetAddress, isReturn: false);
|
||||
}
|
||||
}
|
||||
}
|
@ -204,15 +204,15 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
context.BranchIfTrue(lblBigEndian, GetFlag(PState.EFlag));
|
||||
|
||||
Load(op.Rt, 0, WordSizeLog2);
|
||||
Load(op.Rt | 1, 4, WordSizeLog2);
|
||||
Load(op.Rt, 0, WordSizeLog2);
|
||||
Load(op.Rt2, 4, WordSizeLog2);
|
||||
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblBigEndian);
|
||||
|
||||
Load(op.Rt | 1, 0, WordSizeLog2);
|
||||
Load(op.Rt, 4, WordSizeLog2);
|
||||
Load(op.Rt2, 0, WordSizeLog2);
|
||||
Load(op.Rt, 4, WordSizeLog2);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
}
|
||||
@ -237,15 +237,15 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
context.BranchIfTrue(lblBigEndian, GetFlag(PState.EFlag));
|
||||
|
||||
Store(op.Rt, 0, WordSizeLog2);
|
||||
Store(op.Rt | 1, 4, WordSizeLog2);
|
||||
Store(op.Rt, 0, WordSizeLog2);
|
||||
Store(op.Rt2, 4, WordSizeLog2);
|
||||
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblBigEndian);
|
||||
|
||||
Store(op.Rt | 1, 0, WordSizeLog2);
|
||||
Store(op.Rt, 4, WordSizeLog2);
|
||||
Store(op.Rt2, 0, WordSizeLog2);
|
||||
Store(op.Rt, 4, WordSizeLog2);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
}
|
||||
|
@ -172,13 +172,13 @@ namespace ARMeilleure.Instructions
|
||||
context.BranchIfTrue(lblBigEndian, GetFlag(PState.EFlag));
|
||||
|
||||
SetIntA32(context, op.Rt, valueLow);
|
||||
SetIntA32(context, op.Rt | 1, valueHigh);
|
||||
SetIntA32(context, op.Rt2, valueHigh);
|
||||
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblBigEndian);
|
||||
|
||||
SetIntA32(context, op.Rt | 1, valueLow);
|
||||
SetIntA32(context, op.Rt2, valueLow);
|
||||
SetIntA32(context, op.Rt, valueHigh);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
@ -195,7 +195,7 @@ namespace ARMeilleure.Instructions
|
||||
// Split the result into 2 words (based on endianness)
|
||||
|
||||
Operand lo = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt));
|
||||
Operand hi = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt | 1));
|
||||
Operand hi = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt2));
|
||||
|
||||
Operand lblBigEndian = Label();
|
||||
Operand lblEnd = Label();
|
||||
|
@ -123,6 +123,41 @@ namespace ARMeilleure.Instructions
|
||||
context.CurrOp is OpCodeSimdMemSs);
|
||||
}
|
||||
|
||||
public static Operand EmitReadInt(ArmEmitterContext context, Operand address, int size)
|
||||
{
|
||||
Operand temp = context.AllocateLocal(size == 3 ? OperandType.I64 : OperandType.I32);
|
||||
|
||||
Operand lblSlowPath = Label();
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand physAddr = EmitPtPointerLoad(context, address, lblSlowPath, write: false, size);
|
||||
|
||||
Operand value = default;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: value = context.Load8 (physAddr); break;
|
||||
case 1: value = context.Load16(physAddr); break;
|
||||
case 2: value = context.Load (OperandType.I32, physAddr); break;
|
||||
case 3: value = context.Load (OperandType.I64, physAddr); break;
|
||||
}
|
||||
|
||||
context.Copy(temp, value);
|
||||
|
||||
if (!context.Memory.Type.IsHostMapped())
|
||||
{
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblSlowPath, BasicBlockFrequency.Cold);
|
||||
|
||||
context.Copy(temp, EmitReadIntFallback(context, address, size));
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
private static void EmitReadInt(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
Operand lblSlowPath = Label();
|
||||
@ -419,6 +454,11 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
|
||||
private static void EmitReadIntFallback(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
SetInt(context, rt, EmitReadIntFallback(context, address, size));
|
||||
}
|
||||
|
||||
private static Operand EmitReadIntFallback(ArmEmitterContext context, Operand address, int size)
|
||||
{
|
||||
MethodInfo info = null;
|
||||
|
||||
@ -430,7 +470,7 @@ namespace ARMeilleure.Instructions
|
||||
case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); break;
|
||||
}
|
||||
|
||||
SetInt(context, rt, context.Call(info, address));
|
||||
return context.Call(info, address);
|
||||
}
|
||||
|
||||
private static void EmitReadVectorFallback(
|
||||
|
@ -25,7 +25,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Mla(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluMla op = (OpCode32AluMla)context.CurrOp;
|
||||
IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp;
|
||||
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
@ -43,7 +43,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Mls(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluMla op = (OpCode32AluMla)context.CurrOp;
|
||||
IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp;
|
||||
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
@ -71,7 +71,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
private static void EmitSmmul(ArmEmitterContext context, MullFlags flags)
|
||||
{
|
||||
OpCode32AluMla op = (OpCode32AluMla)context.CurrOp;
|
||||
IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp;
|
||||
|
||||
Operand n = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rn));
|
||||
Operand m = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rm));
|
||||
@ -99,7 +99,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Smla__(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluMla op = (OpCode32AluMla)context.CurrOp;
|
||||
IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp;
|
||||
|
||||
Operand n = GetIntA32(context, op.Rn);
|
||||
Operand m = GetIntA32(context, op.Rm);
|
||||
@ -142,7 +142,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Smlal__(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp;
|
||||
IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp;
|
||||
|
||||
Operand n = GetIntA32(context, op.Rn);
|
||||
Operand m = GetIntA32(context, op.Rm);
|
||||
@ -180,7 +180,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Smlaw_(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluMla op = (OpCode32AluMla)context.CurrOp;
|
||||
IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp;
|
||||
|
||||
Operand n = GetIntA32(context, op.Rn);
|
||||
Operand m = GetIntA32(context, op.Rm);
|
||||
@ -210,7 +210,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Smul__(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluMla op = (OpCode32AluMla)context.CurrOp;
|
||||
IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp;
|
||||
|
||||
Operand n = GetIntA32(context, op.Rn);
|
||||
Operand m = GetIntA32(context, op.Rm);
|
||||
@ -240,7 +240,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Smull(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp;
|
||||
IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp;
|
||||
|
||||
Operand n = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rn));
|
||||
Operand m = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rm));
|
||||
@ -261,7 +261,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Smulw_(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluMla op = (OpCode32AluMla)context.CurrOp;
|
||||
IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp;
|
||||
|
||||
Operand n = GetIntA32(context, op.Rn);
|
||||
Operand m = GetIntA32(context, op.Rm);
|
||||
@ -285,7 +285,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Umaal(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp;
|
||||
IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp;
|
||||
|
||||
Operand n = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rn));
|
||||
Operand m = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rm));
|
||||
@ -310,7 +310,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Umull(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp;
|
||||
IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp;
|
||||
|
||||
Operand n = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rn));
|
||||
Operand m = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rm));
|
||||
@ -331,7 +331,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
private static void EmitMlal(ArmEmitterContext context, bool signed)
|
||||
{
|
||||
OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp;
|
||||
IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp;
|
||||
|
||||
Operand n = GetIntA32(context, op.Rn);
|
||||
Operand m = GetIntA32(context, op.Rm);
|
||||
|
@ -777,6 +777,13 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vmlal_I(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||
|
||||
EmitVectorTernaryLongOpI32(context, (d, n, m) => context.Add(d, context.Multiply(n, m)), !op.U);
|
||||
}
|
||||
|
||||
public static void Vmls_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
@ -992,6 +999,13 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vpaddl(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
|
||||
|
||||
EmitVectorPairwiseLongOpI32(context, (op1, op2) => context.Add(op1, op2), (op.Opc & 1) == 0);
|
||||
}
|
||||
|
||||
public static void Vpmax_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
@ -1014,7 +1028,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorPairwiseOpI32(context, (op1, op2) =>
|
||||
EmitVectorPairwiseOpI32(context, (op1, op2) =>
|
||||
{
|
||||
Operand greater = op.U ? context.ICompareGreaterUI(op1, op2) : context.ICompareGreater(op1, op2);
|
||||
return context.ConditionalSelect(greater, op1, op2);
|
||||
@ -1052,6 +1066,62 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vqadd(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||
|
||||
EmitSaturatingAddSubBinaryOp(context, add: true, !op.U);
|
||||
}
|
||||
|
||||
public static void Vqdmulh(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||
int eSize = 8 << op.Size;
|
||||
|
||||
EmitVectorBinaryOpI32(context, (op1, op2) =>
|
||||
{
|
||||
if (op.Size == 2)
|
||||
{
|
||||
op1 = context.SignExtend32(OperandType.I64, op1);
|
||||
op2 = context.SignExtend32(OperandType.I64, op2);
|
||||
}
|
||||
|
||||
Operand res = context.Multiply(op1, op2);
|
||||
res = context.ShiftRightSI(res, Const(eSize - 1));
|
||||
res = EmitSatQ(context, res, eSize, signedSrc: true, signedDst: true);
|
||||
|
||||
if (op.Size == 2)
|
||||
{
|
||||
res = context.ConvertI64ToI32(res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}, signed: true);
|
||||
}
|
||||
|
||||
public static void Vqmovn(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdMovn op = (OpCode32SimdMovn)context.CurrOp;
|
||||
|
||||
bool signed = !op.Q;
|
||||
|
||||
EmitVectorUnaryNarrowOp32(context, (op1) => EmitSatQ(context, op1, 8 << op.Size, signed, signed), signed);
|
||||
}
|
||||
|
||||
public static void Vqmovun(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdMovn op = (OpCode32SimdMovn)context.CurrOp;
|
||||
|
||||
EmitVectorUnaryNarrowOp32(context, (op1) => EmitSatQ(context, op1, 8 << op.Size, signedSrc: true, signedDst: false), signed: true);
|
||||
}
|
||||
|
||||
public static void Vqsub(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||
|
||||
EmitSaturatingAddSubBinaryOp(context, add: false, !op.U);
|
||||
}
|
||||
|
||||
public static void Vrev(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdRev op = (OpCode32SimdRev)context.CurrOp;
|
||||
@ -1202,6 +1272,30 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vrhadd(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||
|
||||
EmitVectorBinaryOpI32(context, (op1, op2) =>
|
||||
{
|
||||
if (op.Size == 2)
|
||||
{
|
||||
op1 = context.ZeroExtend32(OperandType.I64, op1);
|
||||
op2 = context.ZeroExtend32(OperandType.I64, op2);
|
||||
}
|
||||
|
||||
Operand res = context.Add(context.Add(op1, op2), Const(op1.Type, 1L));
|
||||
res = context.ShiftRightUI(res, Const(1));
|
||||
|
||||
if (op.Size == 2)
|
||||
{
|
||||
res = context.ConvertI64ToI32(res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}, !op.U);
|
||||
}
|
||||
|
||||
public static void Vrsqrte(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdSqrte op = (OpCode32SimdSqrte)context.CurrOp;
|
||||
@ -1349,6 +1443,13 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vsubl_I(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdRegLong op = (OpCode32SimdRegLong)context.CurrOp;
|
||||
|
||||
EmitVectorBinaryLongOpI32(context, (op1, op2) => context.Subtract(op1, op2), !op.U);
|
||||
}
|
||||
|
||||
public static void Vsubw_I(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdRegWide op = (OpCode32SimdRegWide)context.CurrOp;
|
||||
@ -1356,6 +1457,46 @@ namespace ARMeilleure.Instructions
|
||||
EmitVectorBinaryWideOpI32(context, (op1, op2) => context.Subtract(op1, op2), !op.U);
|
||||
}
|
||||
|
||||
private static void EmitSaturatingAddSubBinaryOp(ArmEmitterContext context, bool add, bool signed)
|
||||
{
|
||||
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
|
||||
|
||||
EmitVectorBinaryOpI32(context, (ne, me) =>
|
||||
{
|
||||
if (op.Size <= 2)
|
||||
{
|
||||
if (op.Size == 2)
|
||||
{
|
||||
ne = signed ? context.SignExtend32(OperandType.I64, ne) : context.ZeroExtend32(OperandType.I64, ne);
|
||||
me = signed ? context.SignExtend32(OperandType.I64, me) : context.ZeroExtend32(OperandType.I64, me);
|
||||
}
|
||||
|
||||
Operand res = add ? context.Add(ne, me) : context.Subtract(ne, me);
|
||||
|
||||
res = EmitSatQ(context, res, 8 << op.Size, signedSrc: true, signed);
|
||||
|
||||
if (op.Size == 2)
|
||||
{
|
||||
res = context.ConvertI64ToI32(res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
else if (add) /* if (op.Size == 3) */
|
||||
{
|
||||
return signed
|
||||
? EmitBinarySignedSatQAdd(context, ne, me)
|
||||
: EmitBinaryUnsignedSatQAdd(context, ne, me);
|
||||
}
|
||||
else /* if (sub) */
|
||||
{
|
||||
return signed
|
||||
? EmitBinarySignedSatQSub(context, ne, me)
|
||||
: EmitBinaryUnsignedSatQSub(context, ne, me);
|
||||
}
|
||||
}, signed);
|
||||
}
|
||||
|
||||
private static void EmitSse41MaxMinNumOpF32(ArmEmitterContext context, bool isMaxNum, bool scalar)
|
||||
{
|
||||
IOpCode32Simd op = (IOpCode32Simd)context.CurrOp;
|
||||
|
@ -323,6 +323,60 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
// VRINTA (vector).
|
||||
public static void Vrinta_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorUnaryOpF32(context, (m) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, m));
|
||||
}
|
||||
|
||||
// VRINTM (vector).
|
||||
public static void Vrintm_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
EmitVectorUnaryOpSimd32(context, (m) =>
|
||||
{
|
||||
return context.AddIntrinsic(Intrinsic.X86Roundps, m, Const(X86GetRoundControl(FPRoundingMode.TowardsMinusInfinity)));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(Math.Floor), m));
|
||||
}
|
||||
}
|
||||
|
||||
// VRINTN (vector).
|
||||
public static void Vrintn_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
EmitVectorUnaryOpSimd32(context, (m) =>
|
||||
{
|
||||
return context.AddIntrinsic(Intrinsic.X86Roundps, m, Const(X86GetRoundControl(FPRoundingMode.ToNearest)));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryOpF32(context, (m) => EmitRoundMathCall(context, MidpointRounding.ToEven, m));
|
||||
}
|
||||
}
|
||||
|
||||
// VRINTP (vector).
|
||||
public static void Vrintp_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
EmitVectorUnaryOpSimd32(context, (m) =>
|
||||
{
|
||||
return context.AddIntrinsic(Intrinsic.X86Roundps, m, Const(X86GetRoundControl(FPRoundingMode.TowardsPlusInfinity)));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(Math.Ceiling), m));
|
||||
}
|
||||
}
|
||||
|
||||
// VRINTZ (floating-point).
|
||||
public static void Vrint_Z(ArmEmitterContext context)
|
||||
{
|
||||
|
@ -1281,7 +1281,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void EmitSseOrAvxExitFtzAndDazModesOpF(ArmEmitterContext context, Operand isTrue = default)
|
||||
{
|
||||
isTrue = isTrue == default
|
||||
isTrue = isTrue == default
|
||||
? context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpcrFz)))
|
||||
: isTrue;
|
||||
|
||||
@ -1352,7 +1352,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
if (op.Size <= 2)
|
||||
{
|
||||
de = EmitSatQ(context, emit(ne), op.Size, signedSrc: true, signedDst: true);
|
||||
de = EmitSignedSrcSatQ(context, emit(ne), op.Size, signedDst: true);
|
||||
}
|
||||
else /* if (op.Size == 3) */
|
||||
{
|
||||
@ -1419,15 +1419,18 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
Operand temp = add ? context.Add(ne, me) : context.Subtract(ne, me);
|
||||
|
||||
de = EmitSatQ(context, temp, op.Size, signedSrc: true, signedDst: signed);
|
||||
de = EmitSignedSrcSatQ(context, temp, op.Size, signedDst: signed);
|
||||
}
|
||||
else if (add) /* if (op.Size == 3) */
|
||||
else /* if (op.Size == 3) */
|
||||
{
|
||||
de = EmitBinarySatQAdd(context, ne, me, signed);
|
||||
}
|
||||
else /* if (sub) */
|
||||
{
|
||||
de = EmitBinarySatQSub(context, ne, me, signed);
|
||||
if (add)
|
||||
{
|
||||
de = signed ? EmitBinarySignedSatQAdd(context, ne, me) : EmitBinaryUnsignedSatQAdd(context, ne, me);
|
||||
}
|
||||
else /* if (sub) */
|
||||
{
|
||||
de = signed ? EmitBinarySignedSatQSub(context, ne, me) : EmitBinaryUnsignedSatQSub(context, ne, me);
|
||||
}
|
||||
}
|
||||
|
||||
res = EmitVectorInsert(context, res, de, index, op.Size);
|
||||
@ -1445,11 +1448,11 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
Operand temp = context.Add(ne, me);
|
||||
|
||||
de = EmitSatQ(context, temp, op.Size, signedSrc: true, signedDst: signed);
|
||||
de = EmitSignedSrcSatQ(context, temp, op.Size, signedDst: signed);
|
||||
}
|
||||
else /* if (op.Size == 3) */
|
||||
{
|
||||
de = EmitBinarySatQAccumulate(context, ne, me, signed);
|
||||
de = signed ? EmitBinarySignedSatQAcc(context, ne, me) : EmitBinaryUnsignedSatQAcc(context, ne, me);
|
||||
}
|
||||
|
||||
res = EmitVectorInsert(context, res, de, index, op.Size);
|
||||
@ -1475,7 +1478,7 @@ namespace ARMeilleure.Instructions
|
||||
me = EmitVectorExtract(context, ((OpCodeSimdReg)op).Rm, index, op.Size, signed);
|
||||
}
|
||||
|
||||
Operand de = EmitSatQ(context, emit(ne, me), op.Size, true, signed);
|
||||
Operand de = EmitSignedSrcSatQ(context, emit(ne, me), op.Size, signedDst: signed);
|
||||
|
||||
res = EmitVectorInsert(context, res, de, index, op.Size);
|
||||
}
|
||||
@ -1520,7 +1523,9 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size + 1, signedSrc);
|
||||
|
||||
Operand temp = EmitSatQ(context, ne, op.Size, signedSrc, signedDst);
|
||||
Operand temp = signedSrc
|
||||
? EmitSignedSrcSatQ(context, ne, op.Size, signedDst)
|
||||
: EmitUnsignedSrcSatQ(context, ne, op.Size, signedDst);
|
||||
|
||||
res = EmitVectorInsert(context, res, temp, part + index, op.Size);
|
||||
}
|
||||
@ -1528,74 +1533,248 @@ namespace ARMeilleure.Instructions
|
||||
context.Copy(d, res);
|
||||
}
|
||||
|
||||
// TSrc (16bit, 32bit, 64bit; signed, unsigned) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
||||
public static Operand EmitSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedSrc, bool signedDst)
|
||||
// TSrc (16bit, 32bit, 64bit; signed) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
||||
// long SignedSrcSignedDstSatQ(long op, int size); ulong SignedSrcUnsignedDstSatQ(long op, int size);
|
||||
public static Operand EmitSignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
|
||||
{
|
||||
if ((uint)sizeDst > 2u)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(sizeDst));
|
||||
}
|
||||
Debug.Assert(op.Type == OperandType.I64 && (uint)sizeDst <= 2u);
|
||||
|
||||
MethodInfo info;
|
||||
Operand lbl1 = Label();
|
||||
Operand lblEnd = Label();
|
||||
|
||||
if (signedSrc)
|
||||
{
|
||||
info = signedDst
|
||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcSignedDstSatQ))
|
||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcUnsignedDstSatQ));
|
||||
}
|
||||
else
|
||||
{
|
||||
info = signedDst
|
||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcSignedDstSatQ))
|
||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcUnsignedDstSatQ));
|
||||
}
|
||||
int eSize = 8 << sizeDst;
|
||||
|
||||
return context.Call(info, op, Const(sizeDst));
|
||||
Operand maxT = signedDst ? Const((1L << (eSize - 1)) - 1L) : Const((1UL << eSize) - 1UL);
|
||||
Operand minT = signedDst ? Const(-(1L << (eSize - 1))) : Const(0UL);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||
|
||||
context.BranchIf(lbl1, res, maxT, Comparison.LessOrEqual);
|
||||
context.Copy(res, maxT);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl1);
|
||||
context.BranchIf(lblEnd, res, minT, Comparison.GreaterOrEqual);
|
||||
context.Copy(res, minT);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// TSrc (64bit) == TDst (64bit); signed.
|
||||
public static Operand EmitUnarySignedSatQAbsOrNeg(ArmEmitterContext context, Operand op)
|
||||
// TSrc (16bit, 32bit, 64bit; unsigned) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
||||
// long UnsignedSrcSignedDstSatQ(ulong op, int size); ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size);
|
||||
public static Operand EmitUnsignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
|
||||
{
|
||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
||||
Debug.Assert(op.Type == OperandType.I64 && (uint)sizeDst <= 2u);
|
||||
|
||||
return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnarySignedSatQAbsOrNeg)), op);
|
||||
Operand lblEnd = Label();
|
||||
|
||||
int eSize = 8 << sizeDst;
|
||||
|
||||
Operand maxL = signedDst ? Const((1L << (eSize - 1)) - 1L) : Const((1UL << eSize) - 1UL);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||
|
||||
context.BranchIf(lblEnd, res, maxL, Comparison.LessOrEqualUI);
|
||||
context.Copy(res, maxL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
||||
public static Operand EmitBinarySatQAdd(ArmEmitterContext context, Operand op1, Operand op2, bool signed)
|
||||
// long UnarySignedSatQAbsOrNeg(long op);
|
||||
private static Operand EmitUnarySignedSatQAbsOrNeg(ArmEmitterContext context, Operand op)
|
||||
{
|
||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
|
||||
MethodInfo info = signed
|
||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAdd))
|
||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAdd));
|
||||
Operand lblEnd = Label();
|
||||
|
||||
return context.Call(info, op1, op2);
|
||||
Operand minL = Const(long.MinValue);
|
||||
Operand maxL = Const(long.MaxValue);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||
|
||||
context.BranchIf(lblEnd, res, minL, Comparison.NotEqual);
|
||||
context.Copy(res, maxL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
||||
public static Operand EmitBinarySatQSub(ArmEmitterContext context, Operand op1, Operand op2, bool signed)
|
||||
// long BinarySignedSatQAdd(long op1, long op2);
|
||||
public static Operand EmitBinarySignedSatQAdd(ArmEmitterContext context, Operand op1, Operand op2)
|
||||
{
|
||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
||||
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||
|
||||
MethodInfo info = signed
|
||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQSub))
|
||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQSub));
|
||||
Operand lblEnd = Label();
|
||||
|
||||
return context.Call(info, op1, op2);
|
||||
Operand minL = Const(long.MinValue);
|
||||
Operand maxL = Const(long.MaxValue);
|
||||
Operand zero = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||
|
||||
Operand left = context.BitwiseNot(context.BitwiseExclusiveOr(op1, op2));
|
||||
Operand right = context.BitwiseExclusiveOr(op1, res);
|
||||
context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zero, Comparison.GreaterOrEqual);
|
||||
|
||||
Operand isPositive = context.ICompareGreaterOrEqual(op1, zero);
|
||||
context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
||||
public static Operand EmitBinarySatQAccumulate(ArmEmitterContext context, Operand op1, Operand op2, bool signed)
|
||||
// ulong BinaryUnsignedSatQAdd(ulong op1, ulong op2);
|
||||
public static Operand EmitBinaryUnsignedSatQAdd(ArmEmitterContext context, Operand op1, Operand op2)
|
||||
{
|
||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
||||
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||
|
||||
MethodInfo info = signed
|
||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAcc))
|
||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAcc));
|
||||
Operand lblEnd = Label();
|
||||
|
||||
return context.Call(info, op1, op2);
|
||||
Operand maxUL = Const(ulong.MaxValue);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||
|
||||
context.BranchIf(lblEnd, res, op1, Comparison.GreaterOrEqualUI);
|
||||
context.Copy(res, maxUL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// long BinarySignedSatQSub(long op1, long op2);
|
||||
public static Operand EmitBinarySignedSatQSub(ArmEmitterContext context, Operand op1, Operand op2)
|
||||
{
|
||||
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand minL = Const(long.MinValue);
|
||||
Operand maxL = Const(long.MaxValue);
|
||||
Operand zero = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Subtract(op1, op2));
|
||||
|
||||
Operand left = context.BitwiseExclusiveOr(op1, op2);
|
||||
Operand right = context.BitwiseExclusiveOr(op1, res);
|
||||
context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zero, Comparison.GreaterOrEqual);
|
||||
|
||||
Operand isPositive = context.ICompareGreaterOrEqual(op1, zero);
|
||||
context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// ulong BinaryUnsignedSatQSub(ulong op1, ulong op2);
|
||||
public static Operand EmitBinaryUnsignedSatQSub(ArmEmitterContext context, Operand op1, Operand op2)
|
||||
{
|
||||
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand zero = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Subtract(op1, op2));
|
||||
|
||||
context.BranchIf(lblEnd, op1, op2, Comparison.GreaterOrEqualUI);
|
||||
context.Copy(res, zero);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// long BinarySignedSatQAcc(ulong op1, long op2);
|
||||
private static Operand EmitBinarySignedSatQAcc(ArmEmitterContext context, Operand op1, Operand op2)
|
||||
{
|
||||
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||
|
||||
Operand lbl1 = Label();
|
||||
Operand lbl2 = Label();
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand maxL = Const(long.MaxValue);
|
||||
Operand zero = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||
|
||||
context.BranchIf(lbl1, op1, maxL, Comparison.GreaterUI);
|
||||
Operand notOp2AndRes = context.BitwiseAnd(context.BitwiseNot(op2), res);
|
||||
context.BranchIf(lblEnd, notOp2AndRes, zero, Comparison.GreaterOrEqual);
|
||||
context.Copy(res, maxL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl1);
|
||||
context.BranchIf(lbl2, op2, zero, Comparison.Less);
|
||||
context.Copy(res, maxL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl2);
|
||||
context.BranchIf(lblEnd, res, maxL, Comparison.LessOrEqualUI);
|
||||
context.Copy(res, maxL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// ulong BinaryUnsignedSatQAcc(long op1, ulong op2);
|
||||
private static Operand EmitBinaryUnsignedSatQAcc(ArmEmitterContext context, Operand op1, Operand op2)
|
||||
{
|
||||
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||
|
||||
Operand lbl1 = Label();
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand maxUL = Const(ulong.MaxValue);
|
||||
Operand maxL = Const(long.MaxValue);
|
||||
Operand zero = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||
|
||||
context.BranchIf(lbl1, op1, zero, Comparison.Less);
|
||||
context.BranchIf(lblEnd, res, op1, Comparison.GreaterOrEqualUI);
|
||||
context.Copy(res, maxUL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl1);
|
||||
context.BranchIf(lblEnd, op2, maxL, Comparison.GreaterUI);
|
||||
context.BranchIf(lblEnd, res, zero, Comparison.GreaterOrEqual);
|
||||
context.Copy(res, zero);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public static Operand EmitFloatAbs(ArmEmitterContext context, Operand value, bool single, bool vector)
|
||||
|
@ -219,6 +219,25 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
// Integer
|
||||
|
||||
public static void EmitVectorUnaryAccumulateOpI32(ArmEmitterContext context, Func1I emit, bool signed)
|
||||
{
|
||||
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
|
||||
|
||||
Operand res = GetVecA32(op.Qd);
|
||||
|
||||
int elems = op.GetBytesCount() >> op.Size;
|
||||
|
||||
for (int index = 0; index < elems; index++)
|
||||
{
|
||||
Operand de = EmitVectorExtract32(context, op.Qd, op.Id + index, op.Size, signed);
|
||||
Operand me = EmitVectorExtract32(context, op.Qm, op.Im + index, op.Size, signed);
|
||||
|
||||
res = EmitVectorInsert(context, res, context.Add(de, emit(me)), op.Id + index, op.Size);
|
||||
}
|
||||
|
||||
context.Copy(GetVecA32(op.Qd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorUnaryOpI32(ArmEmitterContext context, Func1I emit, bool signed)
|
||||
{
|
||||
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
|
||||
@ -385,6 +404,18 @@ namespace ARMeilleure.Instructions
|
||||
EmitVectorUnaryOpI32(context, emit, true);
|
||||
}
|
||||
|
||||
public static void EmitVectorUnaryOpSx32(ArmEmitterContext context, Func1I emit, bool accumulate)
|
||||
{
|
||||
if (accumulate)
|
||||
{
|
||||
EmitVectorUnaryAccumulateOpI32(context, emit, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryOpI32(context, emit, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpSx32(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorBinaryOpI32(context, emit, true);
|
||||
@ -400,6 +431,18 @@ namespace ARMeilleure.Instructions
|
||||
EmitVectorUnaryOpI32(context, emit, false);
|
||||
}
|
||||
|
||||
public static void EmitVectorUnaryOpZx32(ArmEmitterContext context, Func1I emit, bool accumulate)
|
||||
{
|
||||
if (accumulate)
|
||||
{
|
||||
EmitVectorUnaryAccumulateOpI32(context, emit, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryOpI32(context, emit, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpZx32(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorBinaryOpI32(context, emit, false);
|
||||
@ -592,6 +635,34 @@ namespace ARMeilleure.Instructions
|
||||
context.Copy(GetVecA32(op.Qd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorPairwiseLongOpI32(ArmEmitterContext context, Func2I emit, bool signed)
|
||||
{
|
||||
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
|
||||
|
||||
int elems = (op.Q ? 16 : 8) >> op.Size;
|
||||
int pairs = elems >> 1;
|
||||
int id = (op.Vd & 1) * pairs;
|
||||
|
||||
Operand res = GetVecA32(op.Qd);
|
||||
|
||||
for (int index = 0; index < pairs; index++)
|
||||
{
|
||||
int pairIndex = index << 1;
|
||||
Operand m1 = EmitVectorExtract32(context, op.Qm, op.Im + pairIndex, op.Size, signed);
|
||||
Operand m2 = EmitVectorExtract32(context, op.Qm, op.Im + pairIndex + 1, op.Size, signed);
|
||||
|
||||
if (op.Size == 2)
|
||||
{
|
||||
m1 = signed ? context.SignExtend32(OperandType.I64, m1) : context.ZeroExtend32(OperandType.I64, m1);
|
||||
m2 = signed ? context.SignExtend32(OperandType.I64, m2) : context.ZeroExtend32(OperandType.I64, m2);
|
||||
}
|
||||
|
||||
res = EmitVectorInsert(context, res, emit(m1, m2), id + index, op.Size + 1);
|
||||
}
|
||||
|
||||
context.Copy(GetVecA32(op.Qd), res);
|
||||
}
|
||||
|
||||
// Narrow
|
||||
|
||||
public static void EmitVectorUnaryNarrowOp32(ArmEmitterContext context, Func1I emit, bool signed = false)
|
||||
|
@ -1004,7 +1004,7 @@ namespace ARMeilleure.Instructions
|
||||
e = EmitShrImm64(context, e, signedSrc, roundConst, shift); // shift <= 32
|
||||
}
|
||||
|
||||
e = EmitSatQ(context, e, op.Size, signedSrc, signedDst);
|
||||
e = signedSrc ? EmitSignedSrcSatQ(context, e, op.Size, signedDst) : EmitUnsignedSrcSatQ(context, e, op.Size, signedDst);
|
||||
|
||||
res = EmitVectorInsert(context, res, e, part + index, op.Size);
|
||||
}
|
||||
|
@ -33,64 +33,24 @@ namespace ARMeilleure.Instructions
|
||||
EmitShrImmSaturatingNarrowOp(context, op.U ? ShrImmSaturatingNarrowFlags.VectorZxZx : ShrImmSaturatingNarrowFlags.VectorSxSx);
|
||||
}
|
||||
|
||||
public static void Vqshrun(ArmEmitterContext context)
|
||||
{
|
||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx);
|
||||
}
|
||||
|
||||
public static void Vrshr(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp;
|
||||
int shift = GetImmShr(op);
|
||||
long roundConst = 1L << (shift - 1);
|
||||
EmitRoundShrImmOp(context, accumulate: false);
|
||||
}
|
||||
|
||||
if (op.U)
|
||||
{
|
||||
if (op.Size < 2)
|
||||
{
|
||||
EmitVectorUnaryOpZx32(context, (op1) =>
|
||||
{
|
||||
op1 = context.Add(op1, Const(op1.Type, roundConst));
|
||||
public static void Vrshrn(ArmEmitterContext context)
|
||||
{
|
||||
EmitRoundShrImmNarrowOp(context, signed: false);
|
||||
}
|
||||
|
||||
return context.ShiftRightUI(op1, Const(shift));
|
||||
});
|
||||
}
|
||||
else if (op.Size == 2)
|
||||
{
|
||||
EmitVectorUnaryOpZx32(context, (op1) =>
|
||||
{
|
||||
op1 = context.ZeroExtend32(OperandType.I64, op1);
|
||||
op1 = context.Add(op1, Const(op1.Type, roundConst));
|
||||
|
||||
return context.ConvertI64ToI32(context.ShiftRightUI(op1, Const(shift)));
|
||||
});
|
||||
}
|
||||
else /* if (op.Size == 3) */
|
||||
{
|
||||
EmitVectorUnaryOpZx32(context, (op1) => EmitShrImm64(context, op1, signed: false, roundConst, shift));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (op.Size < 2)
|
||||
{
|
||||
EmitVectorUnaryOpSx32(context, (op1) =>
|
||||
{
|
||||
op1 = context.Add(op1, Const(op1.Type, roundConst));
|
||||
|
||||
return context.ShiftRightSI(op1, Const(shift));
|
||||
});
|
||||
}
|
||||
else if (op.Size == 2)
|
||||
{
|
||||
EmitVectorUnaryOpSx32(context, (op1) =>
|
||||
{
|
||||
op1 = context.SignExtend32(OperandType.I64, op1);
|
||||
op1 = context.Add(op1, Const(op1.Type, roundConst));
|
||||
|
||||
return context.ConvertI64ToI32(context.ShiftRightSI(op1, Const(shift)));
|
||||
});
|
||||
}
|
||||
else /* if (op.Size == 3) */
|
||||
{
|
||||
EmitVectorUnaryOpZx32(context, (op1) => EmitShrImm64(context, op1, signed: true, roundConst, shift));
|
||||
}
|
||||
}
|
||||
public static void Vrsra(ArmEmitterContext context)
|
||||
{
|
||||
EmitRoundShrImmOp(context, accumulate: true);
|
||||
}
|
||||
|
||||
public static void Vshl(ArmEmitterContext context)
|
||||
@ -191,6 +151,89 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
public static void EmitRoundShrImmOp(ArmEmitterContext context, bool accumulate)
|
||||
{
|
||||
OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp;
|
||||
int shift = GetImmShr(op);
|
||||
long roundConst = 1L << (shift - 1);
|
||||
|
||||
if (op.U)
|
||||
{
|
||||
if (op.Size < 2)
|
||||
{
|
||||
EmitVectorUnaryOpZx32(context, (op1) =>
|
||||
{
|
||||
op1 = context.Add(op1, Const(op1.Type, roundConst));
|
||||
|
||||
return context.ShiftRightUI(op1, Const(shift));
|
||||
}, accumulate);
|
||||
}
|
||||
else if (op.Size == 2)
|
||||
{
|
||||
EmitVectorUnaryOpZx32(context, (op1) =>
|
||||
{
|
||||
op1 = context.ZeroExtend32(OperandType.I64, op1);
|
||||
op1 = context.Add(op1, Const(op1.Type, roundConst));
|
||||
|
||||
return context.ConvertI64ToI32(context.ShiftRightUI(op1, Const(shift)));
|
||||
}, accumulate);
|
||||
}
|
||||
else /* if (op.Size == 3) */
|
||||
{
|
||||
EmitVectorUnaryOpZx32(context, (op1) => EmitShrImm64(context, op1, signed: false, roundConst, shift), accumulate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (op.Size < 2)
|
||||
{
|
||||
EmitVectorUnaryOpSx32(context, (op1) =>
|
||||
{
|
||||
op1 = context.Add(op1, Const(op1.Type, roundConst));
|
||||
|
||||
return context.ShiftRightSI(op1, Const(shift));
|
||||
}, accumulate);
|
||||
}
|
||||
else if (op.Size == 2)
|
||||
{
|
||||
EmitVectorUnaryOpSx32(context, (op1) =>
|
||||
{
|
||||
op1 = context.SignExtend32(OperandType.I64, op1);
|
||||
op1 = context.Add(op1, Const(op1.Type, roundConst));
|
||||
|
||||
return context.ConvertI64ToI32(context.ShiftRightSI(op1, Const(shift)));
|
||||
}, accumulate);
|
||||
}
|
||||
else /* if (op.Size == 3) */
|
||||
{
|
||||
EmitVectorUnaryOpZx32(context, (op1) => EmitShrImm64(context, op1, signed: true, roundConst, shift), accumulate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitRoundShrImmNarrowOp(ArmEmitterContext context, bool signed)
|
||||
{
|
||||
OpCode32SimdShImm op = (OpCode32SimdShImm)context.CurrOp;
|
||||
|
||||
int shift = GetImmShr(op);
|
||||
long roundConst = 1L << (shift - 1);
|
||||
|
||||
EmitVectorUnaryNarrowOp32(context, (op1) =>
|
||||
{
|
||||
if (op.Size <= 1)
|
||||
{
|
||||
op1 = context.Add(op1, Const(op1.Type, roundConst));
|
||||
op1 = signed ? context.ShiftRightSI(op1, Const(shift)) : context.ShiftRightUI(op1, Const(shift));
|
||||
}
|
||||
else /* if (op.Size == 2 && round) */
|
||||
{
|
||||
op1 = EmitShrImm64(context, op1, signed, roundConst, shift); // shift <= 32
|
||||
}
|
||||
|
||||
return op1;
|
||||
}, signed);
|
||||
}
|
||||
|
||||
private static Operand EmitShlRegOp(ArmEmitterContext context, Operand op, Operand shiftLsB, int size, bool unsigned)
|
||||
{
|
||||
if (shiftLsB.Type == OperandType.I64)
|
||||
@ -289,7 +332,7 @@ namespace ARMeilleure.Instructions
|
||||
op1 = EmitShrImm64(context, op1, signedSrc, roundConst, shift); // shift <= 32
|
||||
}
|
||||
|
||||
return EmitSatQ(context, op1, 8 << op.Size, signedDst);
|
||||
return EmitSatQ(context, op1, 8 << op.Size, signedSrc, signedDst);
|
||||
}, signedSrc);
|
||||
}
|
||||
|
||||
@ -313,15 +356,20 @@ namespace ARMeilleure.Instructions
|
||||
return context.Call(info, value, Const(roundConst), Const(shift));
|
||||
}
|
||||
|
||||
private static Operand EmitSatQ(ArmEmitterContext context, Operand value, int eSize, bool signed)
|
||||
private static Operand EmitSatQ(ArmEmitterContext context, Operand value, int eSize, bool signedSrc, bool signedDst)
|
||||
{
|
||||
Debug.Assert(eSize <= 32);
|
||||
|
||||
long intMin = signed ? -(1L << (eSize - 1)) : 0;
|
||||
long intMax = signed ? (1L << (eSize - 1)) - 1 : (1L << eSize) - 1;
|
||||
long intMin = signedDst ? -(1L << (eSize - 1)) : 0;
|
||||
long intMax = signedDst ? (1L << (eSize - 1)) - 1 : (1L << eSize) - 1;
|
||||
|
||||
Operand gt = context.ICompareGreater(value, Const(value.Type, intMax));
|
||||
Operand lt = context.ICompareLess(value, Const(value.Type, intMin));
|
||||
Operand gt = signedSrc
|
||||
? context.ICompareGreater(value, Const(value.Type, intMax))
|
||||
: context.ICompareGreaterUI(value, Const(value.Type, intMax));
|
||||
|
||||
Operand lt = signedSrc
|
||||
? context.ICompareLess(value, Const(value.Type, intMin))
|
||||
: context.ICompareLessUI(value, Const(value.Type, intMin));
|
||||
|
||||
value = context.ConditionalSelect(gt, Const(value.Type, intMax), value);
|
||||
value = context.ConditionalSelect(lt, Const(value.Type, intMin), value);
|
||||
|
@ -16,18 +16,13 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
OpCode32System op = (OpCode32System)context.CurrOp;
|
||||
|
||||
if (op.Coproc != 15)
|
||||
if (op.Coproc != 15 || op.Opc1 != 0)
|
||||
{
|
||||
InstEmit.Und(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (op.Opc1 != 0)
|
||||
{
|
||||
throw new NotImplementedException($"Unknown MRC Opc1 0x{op.Opc1:X16} at 0x{op.Address:X16}.");
|
||||
}
|
||||
|
||||
MethodInfo info;
|
||||
|
||||
switch (op.CRn)
|
||||
@ -35,7 +30,7 @@ namespace ARMeilleure.Instructions
|
||||
case 13: // Process and Thread Info.
|
||||
if (op.CRm != 0)
|
||||
{
|
||||
throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X} at 0x{op.Address:X} (0x{op.RawOpCode:X}).");
|
||||
}
|
||||
|
||||
switch (op.Opc2)
|
||||
@ -44,7 +39,7 @@ namespace ARMeilleure.Instructions
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032)); break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X} at 0x{op.Address:X} (0x{op.RawOpCode:X}).");
|
||||
}
|
||||
|
||||
break;
|
||||
@ -59,11 +54,11 @@ namespace ARMeilleure.Instructions
|
||||
return; // No-op.
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16} (0x{op.RawOpCode:X}).");
|
||||
}
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16} (0x{op.RawOpCode:X}).");
|
||||
}
|
||||
|
||||
default:
|
||||
@ -77,18 +72,13 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
OpCode32System op = (OpCode32System)context.CurrOp;
|
||||
|
||||
if (op.Coproc != 15)
|
||||
if (op.Coproc != 15 || op.Opc1 != 0)
|
||||
{
|
||||
InstEmit.Und(context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (op.Opc1 != 0)
|
||||
{
|
||||
throw new NotImplementedException($"Unknown MRC Opc1 0x{op.Opc1:X16} at 0x{op.Address:X16}.");
|
||||
}
|
||||
|
||||
MethodInfo info;
|
||||
|
||||
switch (op.CRn)
|
||||
@ -96,7 +86,7 @@ namespace ARMeilleure.Instructions
|
||||
case 13: // Process and Thread Info.
|
||||
if (op.CRm != 0)
|
||||
{
|
||||
throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X} at 0x{op.Address:X} (0x{op.RawOpCode:X}).");
|
||||
}
|
||||
|
||||
switch (op.Opc2)
|
||||
@ -108,13 +98,13 @@ namespace ARMeilleure.Instructions
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidr32)); break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X} at 0x{op.Address:X} (0x{op.RawOpCode:X}).");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown MRC 0x{op.RawOpCode:X8} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown MRC 0x{op.RawOpCode:X} at 0x{op.Address:X}.");
|
||||
}
|
||||
|
||||
if (op.Rt == RegisterAlias.Aarch32Pc)
|
||||
@ -154,13 +144,13 @@ namespace ARMeilleure.Instructions
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)); break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown MRRC Opc1 0x{opc:X16} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown MRRC Opc1 0x{opc:X} at 0x{op.Address:X} (0x{op.RawOpCode:X}).");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown MRRC 0x{op.RawOpCode:X8} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown MRRC 0x{op.RawOpCode:X} at 0x{op.Address:X}.");
|
||||
}
|
||||
|
||||
Operand result = context.Call(info);
|
||||
@ -265,7 +255,7 @@ namespace ARMeilleure.Instructions
|
||||
case 0b1000: // FPEXC
|
||||
throw new NotImplementedException("Supervisor Only");
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown VMRS 0x{op.RawOpCode:X8} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown VMRS 0x{op.RawOpCode:X} at 0x{op.Address:X}.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,7 +278,7 @@ namespace ARMeilleure.Instructions
|
||||
case 0b1000: // FPEXC
|
||||
throw new NotImplementedException("Supervisor Only");
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown VMSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}.");
|
||||
throw new NotImplementedException($"Unknown VMSR 0x{op.RawOpCode:X} at 0x{op.Address:X}.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,6 +545,8 @@ namespace ARMeilleure.Instructions
|
||||
Strexh,
|
||||
Strh,
|
||||
Sxtb16,
|
||||
Tbb,
|
||||
Tbh,
|
||||
Teq,
|
||||
Trap,
|
||||
Tst,
|
||||
@ -601,6 +603,7 @@ namespace ARMeilleure.Instructions
|
||||
Vmin,
|
||||
Vminnm,
|
||||
Vmla,
|
||||
Vmlal,
|
||||
Vmls,
|
||||
Vmlsl,
|
||||
Vmov,
|
||||
@ -618,15 +621,28 @@ namespace ARMeilleure.Instructions
|
||||
Vorn,
|
||||
Vorr,
|
||||
Vpadd,
|
||||
Vpaddl,
|
||||
Vpmax,
|
||||
Vpmin,
|
||||
Vqadd,
|
||||
Vqdmulh,
|
||||
Vqmovn,
|
||||
Vqmovun,
|
||||
Vqrshrn,
|
||||
Vqrshrun,
|
||||
Vqshrn,
|
||||
Vqshrun,
|
||||
Vqsub,
|
||||
Vrev,
|
||||
Vrhadd,
|
||||
Vrint,
|
||||
Vrinta,
|
||||
Vrintm,
|
||||
Vrintn,
|
||||
Vrintp,
|
||||
Vrintx,
|
||||
Vrshr,
|
||||
Vrshrn,
|
||||
Vsel,
|
||||
Vshl,
|
||||
Vshll,
|
||||
@ -643,8 +659,10 @@ namespace ARMeilleure.Instructions
|
||||
Vrecps,
|
||||
Vrsqrte,
|
||||
Vrsqrts,
|
||||
Vrsra,
|
||||
Vsra,
|
||||
Vsub,
|
||||
Vsubl,
|
||||
Vsubw,
|
||||
Vtbl,
|
||||
Vtrn,
|
||||
|
@ -91,7 +91,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else /* if (eSize != 64) */
|
||||
{
|
||||
return SignedSrcSignedDstSatQ(value << shiftLsB, size);
|
||||
return SignedSrcSignedDstSatQ(value << shiftLsB, size); // InstEmitSimdHelper.EmitSignedSrcSatQ(signedDst: true).
|
||||
}
|
||||
}
|
||||
else /* if (shiftLsB == 0) */
|
||||
@ -135,7 +135,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else /* if (eSize != 64) */
|
||||
{
|
||||
return UnsignedSrcUnsignedDstSatQ(value << shiftLsB, size);
|
||||
return UnsignedSrcUnsignedDstSatQ(value << shiftLsB, size); // InstEmitSimdHelper.EmitUnsignedSrcSatQ(signedDst: false).
|
||||
}
|
||||
}
|
||||
else /* if (shiftLsB == 0) */
|
||||
@ -509,7 +509,7 @@ namespace ARMeilleure.Instructions
|
||||
#endregion
|
||||
|
||||
#region "Saturating"
|
||||
public static long SignedSrcSignedDstSatQ(long op, int size)
|
||||
private static long SignedSrcSignedDstSatQ(long op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
@ -536,54 +536,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong SignedSrcUnsignedDstSatQ(long op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
ulong tMaxValue = (1UL << eSize) - 1UL;
|
||||
ulong tMinValue = 0UL;
|
||||
|
||||
if (op > (long)tMaxValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else if (op < (long)tMinValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ulong)op;
|
||||
}
|
||||
}
|
||||
|
||||
public static long UnsignedSrcSignedDstSatQ(ulong op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
long tMaxValue = (1L << (eSize - 1)) - 1L;
|
||||
|
||||
if (op > (ulong)tMaxValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (long)op;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size)
|
||||
private static ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
@ -602,208 +555,6 @@ namespace ARMeilleure.Instructions
|
||||
return op;
|
||||
}
|
||||
}
|
||||
|
||||
public static long UnarySignedSatQAbsOrNeg(long op)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
if (op == long.MinValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return long.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return op;
|
||||
}
|
||||
}
|
||||
|
||||
public static long BinarySignedSatQAdd(long op1, long op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
long add = op1 + op2;
|
||||
|
||||
if ((~(op1 ^ op2) & (op1 ^ add)) < 0L)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
if (op1 < 0L)
|
||||
{
|
||||
return long.MinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return long.MaxValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return add;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong BinaryUnsignedSatQAdd(ulong op1, ulong op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
ulong add = op1 + op2;
|
||||
|
||||
if ((add < op1) && (add < op2))
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return ulong.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return add;
|
||||
}
|
||||
}
|
||||
|
||||
public static long BinarySignedSatQSub(long op1, long op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
long sub = op1 - op2;
|
||||
|
||||
if (((op1 ^ op2) & (op1 ^ sub)) < 0L)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
if (op1 < 0L)
|
||||
{
|
||||
return long.MinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return long.MaxValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong BinaryUnsignedSatQSub(ulong op1, ulong op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
ulong sub = op1 - op2;
|
||||
|
||||
if (op1 < op2)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return ulong.MinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
|
||||
public static long BinarySignedSatQAcc(ulong op1, long op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
if (op1 <= (ulong)long.MaxValue)
|
||||
{
|
||||
// op1 from ulong.MinValue to (ulong)long.MaxValue
|
||||
// op2 from long.MinValue to long.MaxValue
|
||||
|
||||
long add = (long)op1 + op2;
|
||||
|
||||
if ((~op2 & add) < 0L)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return long.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return add;
|
||||
}
|
||||
}
|
||||
else if (op2 >= 0L)
|
||||
{
|
||||
// op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
||||
// op2 from (long)ulong.MinValue to long.MaxValue
|
||||
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return long.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
||||
// op2 from long.MinValue to (long)ulong.MinValue - 1L
|
||||
|
||||
ulong add = op1 + (ulong)op2;
|
||||
|
||||
if (add > (ulong)long.MaxValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return long.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (long)add;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong BinaryUnsignedSatQAcc(long op1, ulong op2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
if (op1 >= 0L)
|
||||
{
|
||||
// op1 from (long)ulong.MinValue to long.MaxValue
|
||||
// op2 from ulong.MinValue to ulong.MaxValue
|
||||
|
||||
ulong add = (ulong)op1 + op2;
|
||||
|
||||
if ((add < (ulong)op1) && (add < op2))
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return ulong.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return add;
|
||||
}
|
||||
}
|
||||
else if (op2 > (ulong)long.MaxValue)
|
||||
{
|
||||
// op1 from long.MinValue to (long)ulong.MinValue - 1L
|
||||
// op2 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
||||
|
||||
return (ulong)op1 + op2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// op1 from long.MinValue to (long)ulong.MinValue - 1L
|
||||
// op2 from ulong.MinValue to (ulong)long.MaxValue
|
||||
|
||||
long add = op1 + (long)op2;
|
||||
|
||||
if (add < (long)ulong.MinValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return ulong.MinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ulong)add;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "Count"
|
||||
|
@ -127,7 +127,7 @@ namespace ARMeilleure.Translation
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpcr)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsr)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); // A32 only.
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032))); // A32 only.
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
|
||||
@ -140,12 +140,6 @@ namespace ARMeilleure.Translation
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)));
|
||||
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAcc)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAdd)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQSub)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAcc)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAdd)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQSub)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32b)));
|
||||
@ -188,8 +182,6 @@ namespace ARMeilleure.Translation
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlReg)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcSignedDstSatQ)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcUnsignedDstSatQ)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)));
|
||||
@ -198,12 +190,9 @@ namespace ARMeilleure.Translation
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnarySignedSatQAbsOrNeg)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlReg)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcSignedDstSatQ)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcUnsignedDstSatQ)));
|
||||
|
||||
SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
|
||||
SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)));
|
||||
|
@ -19,8 +19,6 @@ namespace ARMeilleure.Translation
|
||||
|
||||
public int Count => _count;
|
||||
|
||||
public IntervalTree() { }
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
|
@ -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 = 3585; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 3683; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
|
@ -44,15 +44,11 @@ namespace ARMeilleure.Translation
|
||||
private readonly IJitMemoryAllocator _allocator;
|
||||
private readonly ConcurrentQueue<KeyValuePair<ulong, TranslatedFunction>> _oldFuncs;
|
||||
|
||||
private readonly ConcurrentDictionary<ulong, object> _backgroundSet;
|
||||
private readonly ConcurrentStack<RejitRequest> _backgroundStack;
|
||||
private readonly AutoResetEvent _backgroundTranslatorEvent;
|
||||
private readonly ReaderWriterLock _backgroundTranslatorLock;
|
||||
|
||||
internal TranslatorCache<TranslatedFunction> Functions { get; }
|
||||
internal AddressTable<ulong> FunctionTable { get; }
|
||||
internal EntryTable<uint> CountTable { get; }
|
||||
internal TranslatorStubs Stubs { get; }
|
||||
internal TranslatorQueue Queue { get; }
|
||||
internal IMemoryManager Memory { get; }
|
||||
|
||||
private volatile int _threadCount;
|
||||
@ -67,10 +63,7 @@ namespace ARMeilleure.Translation
|
||||
|
||||
_oldFuncs = new ConcurrentQueue<KeyValuePair<ulong, TranslatedFunction>>();
|
||||
|
||||
_backgroundSet = new ConcurrentDictionary<ulong, object>();
|
||||
_backgroundStack = new ConcurrentStack<RejitRequest>();
|
||||
_backgroundTranslatorEvent = new AutoResetEvent(false);
|
||||
_backgroundTranslatorLock = new ReaderWriterLock();
|
||||
Queue = new TranslatorQueue();
|
||||
|
||||
JitCache.Initialize(allocator);
|
||||
|
||||
@ -87,43 +80,6 @@ namespace ARMeilleure.Translation
|
||||
}
|
||||
}
|
||||
|
||||
private void TranslateStackedSubs()
|
||||
{
|
||||
while (_threadCount != 0)
|
||||
{
|
||||
_backgroundTranslatorLock.AcquireReaderLock(Timeout.Infinite);
|
||||
|
||||
if (_backgroundStack.TryPop(out RejitRequest request) &&
|
||||
_backgroundSet.TryRemove(request.Address, out _))
|
||||
{
|
||||
TranslatedFunction func = Translate(request.Address, request.Mode, highCq: true);
|
||||
|
||||
Functions.AddOrUpdate(request.Address, func.GuestSize, func, (key, oldFunc) =>
|
||||
{
|
||||
EnqueueForDeletion(key, oldFunc);
|
||||
return func;
|
||||
});
|
||||
|
||||
if (PtcProfiler.Enabled)
|
||||
{
|
||||
PtcProfiler.UpdateEntry(request.Address, request.Mode, highCq: true);
|
||||
}
|
||||
|
||||
RegisterFunction(request.Address, func);
|
||||
|
||||
_backgroundTranslatorLock.ReleaseReaderLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
_backgroundTranslatorLock.ReleaseReaderLock();
|
||||
_backgroundTranslatorEvent.WaitOne();
|
||||
}
|
||||
}
|
||||
|
||||
// Wake up any other background translator threads, to encourage them to exit.
|
||||
_backgroundTranslatorEvent.Set();
|
||||
}
|
||||
|
||||
public void Execute(State.ExecutionContext context, ulong address)
|
||||
{
|
||||
if (Interlocked.Increment(ref _threadCount) == 1)
|
||||
@ -155,7 +111,7 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
bool last = i != 0 && i == unboundedThreadCount - 1;
|
||||
|
||||
Thread backgroundTranslatorThread = new Thread(TranslateStackedSubs)
|
||||
Thread backgroundTranslatorThread = new Thread(BackgroundTranslate)
|
||||
{
|
||||
Name = "CPU.BackgroundTranslatorThread." + i,
|
||||
Priority = last ? ThreadPriority.Lowest : ThreadPriority.Normal
|
||||
@ -186,10 +142,9 @@ namespace ARMeilleure.Translation
|
||||
|
||||
if (Interlocked.Decrement(ref _threadCount) == 0)
|
||||
{
|
||||
_backgroundTranslatorEvent.Set();
|
||||
|
||||
ClearJitCache();
|
||||
|
||||
Queue.Dispose();
|
||||
Stubs.Dispose();
|
||||
FunctionTable.Dispose();
|
||||
CountTable.Dispose();
|
||||
@ -317,6 +272,27 @@ namespace ARMeilleure.Translation
|
||||
return new TranslatedFunction(func, counter, funcSize, highCq);
|
||||
}
|
||||
|
||||
private void BackgroundTranslate()
|
||||
{
|
||||
while (_threadCount != 0 && Queue.TryDequeue(out RejitRequest request))
|
||||
{
|
||||
TranslatedFunction func = Translate(request.Address, request.Mode, highCq: true);
|
||||
|
||||
Functions.AddOrUpdate(request.Address, func.GuestSize, func, (key, oldFunc) =>
|
||||
{
|
||||
EnqueueForDeletion(key, oldFunc);
|
||||
return func;
|
||||
});
|
||||
|
||||
if (PtcProfiler.Enabled)
|
||||
{
|
||||
PtcProfiler.UpdateEntry(request.Address, request.Mode, highCq: true);
|
||||
}
|
||||
|
||||
RegisterFunction(request.Address, func);
|
||||
}
|
||||
}
|
||||
|
||||
private struct Range
|
||||
{
|
||||
public ulong Start { get; }
|
||||
@ -504,11 +480,7 @@ namespace ARMeilleure.Translation
|
||||
|
||||
internal void EnqueueForRejit(ulong guestAddress, ExecutionMode mode)
|
||||
{
|
||||
if (_backgroundSet.TryAdd(guestAddress, null))
|
||||
{
|
||||
_backgroundStack.Push(new RejitRequest(guestAddress, mode));
|
||||
_backgroundTranslatorEvent.Set();
|
||||
}
|
||||
Queue.Enqueue(guestAddress, mode);
|
||||
}
|
||||
|
||||
private void EnqueueForDeletion(ulong guestAddress, TranslatedFunction func)
|
||||
@ -542,26 +514,23 @@ namespace ARMeilleure.Translation
|
||||
|
||||
private void ClearRejitQueue(bool allowRequeue)
|
||||
{
|
||||
_backgroundTranslatorLock.AcquireWriterLock(Timeout.Infinite);
|
||||
|
||||
if (allowRequeue)
|
||||
if (!allowRequeue)
|
||||
{
|
||||
while (_backgroundStack.TryPop(out var request))
|
||||
Queue.Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
lock (Queue.Sync)
|
||||
{
|
||||
while (Queue.Count > 0 && Queue.TryDequeue(out RejitRequest request))
|
||||
{
|
||||
if (Functions.TryGetValue(request.Address, out var func) && func.CallCounter != null)
|
||||
{
|
||||
Volatile.Write(ref func.CallCounter.Value, 0);
|
||||
}
|
||||
|
||||
_backgroundSet.TryRemove(request.Address, out _);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_backgroundStack.Clear();
|
||||
}
|
||||
|
||||
_backgroundTranslatorLock.ReleaseWriterLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
121
ARMeilleure/Translation/TranslatorQueue.cs
Normal file
121
ARMeilleure/Translation/TranslatorQueue.cs
Normal file
@ -0,0 +1,121 @@
|
||||
using ARMeilleure.Diagnostics;
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a queue of <see cref="RejitRequest"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This does not necessarily behave like a queue, i.e: a FIFO collection.
|
||||
/// </remarks>
|
||||
sealed class TranslatorQueue : IDisposable
|
||||
{
|
||||
private bool _disposed;
|
||||
private readonly Stack<RejitRequest> _requests;
|
||||
private readonly HashSet<ulong> _requestAddresses;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the object used to synchronize access to the <see cref="TranslatorQueue"/>.
|
||||
/// </summary>
|
||||
public object Sync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of requests in the <see cref="TranslatorQueue"/>.
|
||||
/// </summary>
|
||||
public int Count => _requests.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TranslatorQueue"/> class.
|
||||
/// </summary>
|
||||
public TranslatorQueue()
|
||||
{
|
||||
Sync = new object();
|
||||
|
||||
_requests = new Stack<RejitRequest>();
|
||||
_requestAddresses = new HashSet<ulong>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enqueues a request with the specified <paramref name="address"/> and <paramref name="mode"/>.
|
||||
/// </summary>
|
||||
/// <param name="address">Address of request</param>
|
||||
/// <param name="mode"><see cref="ExecutionMode"/> of request</param>
|
||||
public void Enqueue(ulong address, ExecutionMode mode)
|
||||
{
|
||||
lock (Sync)
|
||||
{
|
||||
if (_requestAddresses.Add(address))
|
||||
{
|
||||
_requests.Push(new RejitRequest(address, mode));
|
||||
|
||||
TranslatorEventSource.Log.RejitQueueAdd(1);
|
||||
|
||||
Monitor.Pulse(Sync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to dequeue a <see cref="RejitRequest"/>. This will block the thread until a <see cref="RejitRequest"/>
|
||||
/// is enqueued or the <see cref="TranslatorQueue"/> is disposed.
|
||||
/// </summary>
|
||||
/// <param name="result"><see cref="RejitRequest"/> dequeued</param>
|
||||
/// <returns><see langword="true"/> on success; otherwise <see langword="false"/></returns>
|
||||
public bool TryDequeue(out RejitRequest result)
|
||||
{
|
||||
while (!_disposed)
|
||||
{
|
||||
lock (Sync)
|
||||
{
|
||||
if (_requests.TryPop(out result))
|
||||
{
|
||||
_requestAddresses.Remove(result.Address);
|
||||
|
||||
TranslatorEventSource.Log.RejitQueueAdd(-1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Monitor.Wait(Sync);
|
||||
}
|
||||
}
|
||||
|
||||
result = default;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the <see cref="TranslatorQueue"/>.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
lock (Sync)
|
||||
{
|
||||
TranslatorEventSource.Log.RejitQueueAdd(-_requests.Count);
|
||||
|
||||
_requests.Clear();
|
||||
_requestAddresses.Clear();
|
||||
|
||||
Monitor.PulseAll(Sync);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resources used by the <see cref="TranslatorQueue"/> instance.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_disposed = true;
|
||||
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
README.md
10
README.md
@ -36,8 +36,8 @@
|
||||
|
||||
## Compatibility
|
||||
|
||||
As of January 2022, Ryujinx has been tested on approximately 3,500 titles; over 3,200 boot past menus and into gameplay, with roughly 2,500 of those being considered playable.
|
||||
You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues). Anyone is free to submit an updated test on an existing game entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already!
|
||||
As of September 2022, Ryujinx has been tested on approximately 3,600 titles; over 3,400 boot past menus and into gameplay, with roughly 2,700 of those being considered playable. You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues).
|
||||
Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already!
|
||||
|
||||
## Usage
|
||||
|
||||
@ -118,11 +118,11 @@ If you'd like to support the project financially, Ryujinx has an active Patreon
|
||||
<img src="https://images.squarespace-cdn.com/content/v1/560c1d39e4b0b4fae0c9cf2a/1567548955044-WVD994WZP76EWF15T0L3/Patreon+Button.png?format=500w" width="150">
|
||||
</a>
|
||||
|
||||
All the developers working on the project do so on their free time, but the project has several expenses:
|
||||
All developers working on the project do so in their free time, but the project has several expenses:
|
||||
* Hackable Nintendo Switch consoles to reverse-engineer the hardware
|
||||
* Additional computer hardware for testing purposes (e.g. GPUs to diagnose graphical bugs, etc.)
|
||||
* Licenses for various software development tools (e.g. Jetbrains, LDN servers, IDA)
|
||||
* Web hosting and infrastructure maintenance
|
||||
* Licenses for various software development tools (e.g. Jetbrains, IDA)
|
||||
* Web hosting and infrastructure maintenance (e.g. LDN servers)
|
||||
|
||||
All funds received through Patreon are considered a donation to support the project. Patrons receive early access to progress reports and exclusive access to developer interviews.
|
||||
|
||||
|
@ -55,7 +55,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||
private uint _processHandle;
|
||||
private ulong _appletResourceId;
|
||||
|
||||
private WritableRegion _workBufferRegion;
|
||||
private MemoryHandle _workBufferMemoryPin;
|
||||
|
||||
private Memory<float> _mixBuffer;
|
||||
@ -98,7 +97,15 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||
_sessionId = 0;
|
||||
}
|
||||
|
||||
public ResultCode Initialize(ref AudioRendererConfiguration parameter, uint processHandle, CpuAddress workBuffer, ulong workBufferSize, int sessionId, ulong appletResourceId, IVirtualMemoryManager memoryManager)
|
||||
public ResultCode Initialize(
|
||||
ref AudioRendererConfiguration parameter,
|
||||
uint processHandle,
|
||||
Memory<byte> workBufferMemory,
|
||||
CpuAddress workBuffer,
|
||||
ulong workBufferSize,
|
||||
int sessionId,
|
||||
ulong appletResourceId,
|
||||
IVirtualMemoryManager memoryManager)
|
||||
{
|
||||
if (!BehaviourContext.CheckValidRevision(parameter.Revision))
|
||||
{
|
||||
@ -134,11 +141,10 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||
|
||||
WorkBufferAllocator workBufferAllocator;
|
||||
|
||||
_workBufferRegion = MemoryManager.GetWritableRegion(workBuffer, (int)workBufferSize);
|
||||
_workBufferRegion.Memory.Span.Fill(0);
|
||||
_workBufferMemoryPin = _workBufferRegion.Memory.Pin();
|
||||
workBufferMemory.Span.Fill(0);
|
||||
_workBufferMemoryPin = workBufferMemory.Pin();
|
||||
|
||||
workBufferAllocator = new WorkBufferAllocator(_workBufferRegion.Memory);
|
||||
workBufferAllocator = new WorkBufferAllocator(workBufferMemory);
|
||||
|
||||
PoolMapper poolMapper = new PoolMapper(processHandle, false);
|
||||
poolMapper.InitializeSystemPool(ref _dspMemoryPoolState, workBuffer, workBufferSize);
|
||||
@ -841,7 +847,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||
_manager.Unregister(this);
|
||||
_terminationEvent.Dispose();
|
||||
_workBufferMemoryPin.Dispose();
|
||||
_workBufferRegion.Dispose();
|
||||
|
||||
if (MemoryManager is IRefCounted rc)
|
||||
{
|
||||
|
@ -305,13 +305,34 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||
/// <param name="workBufferSize">The guest work buffer size.</param>
|
||||
/// <param name="processHandle">The process handle of the application.</param>
|
||||
/// <returns>A <see cref="ResultCode"/> reporting an error or a success.</returns>
|
||||
public ResultCode OpenAudioRenderer(out AudioRenderSystem renderer, IVirtualMemoryManager memoryManager, ref AudioRendererConfiguration parameter, ulong appletResourceUserId, ulong workBufferAddress, ulong workBufferSize, uint processHandle, float volume)
|
||||
public ResultCode OpenAudioRenderer(
|
||||
out AudioRenderSystem renderer,
|
||||
IVirtualMemoryManager memoryManager,
|
||||
ref AudioRendererConfiguration parameter,
|
||||
ulong appletResourceUserId,
|
||||
ulong workBufferAddress,
|
||||
ulong workBufferSize,
|
||||
uint processHandle,
|
||||
float volume)
|
||||
{
|
||||
int sessionId = AcquireSessionId();
|
||||
|
||||
AudioRenderSystem audioRenderer = new AudioRenderSystem(this, _sessionsSystemEvent[sessionId]);
|
||||
|
||||
ResultCode result = audioRenderer.Initialize(ref parameter, processHandle, workBufferAddress, workBufferSize, sessionId, appletResourceUserId, memoryManager);
|
||||
// TODO: Eventually, we should try to use the guest supplied work buffer instead of allocating
|
||||
// our own. However, it was causing problems on some applications that would unmap the memory
|
||||
// before the audio renderer was fully disposed.
|
||||
Memory<byte> workBufferMemory = GC.AllocateArray<byte>((int)workBufferSize, pinned: true);
|
||||
|
||||
ResultCode result = audioRenderer.Initialize(
|
||||
ref parameter,
|
||||
processHandle,
|
||||
workBufferMemory,
|
||||
workBufferAddress,
|
||||
workBufferSize,
|
||||
sessionId,
|
||||
appletResourceUserId,
|
||||
memoryManager);
|
||||
|
||||
if (result == ResultCode.Success)
|
||||
{
|
||||
|
@ -20,7 +20,7 @@
|
||||
"MenuBarOptionsManageUserProfiles": "_Profilverwaltung",
|
||||
"MenuBarActions": "_Aktionen",
|
||||
"MenuBarOptionsSimulateWakeUpMessage": "Aufwachnachricht",
|
||||
"MenuBarActionsScanAmiibo": "Virtualisiere Amiibo",
|
||||
"MenuBarActionsScanAmiibo": "Scanne ein Amiibo",
|
||||
"MenuBarTools": "_Werkzeuge",
|
||||
"MenuBarToolsInstallFirmware": "Firmware installieren",
|
||||
"MenuBarFileToolsInstallFirmwareFromFile": "Installiere Firmware von einer XCI oder einer ZIP Datei",
|
||||
@ -52,8 +52,8 @@
|
||||
"GameListContextMenuOpenModsDirectory": "Mod-Verzeichnis öffnen",
|
||||
"GameListContextMenuOpenModsDirectoryToolTip": "Öffnet das Verzeichnis, welches Mods für die Spiele beinhaltet",
|
||||
"GameListContextMenuCacheManagement": "Cache Verwaltung",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "PPTC Cache löschen",
|
||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "Löscht den PPTC Cache der Anwendung",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "PPTC als ungültig markieren",
|
||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "Markiert den PPTC als ungültig, sodass dieser beim nächsten Spielstart neu erstellt wird",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCache": "Shader Cache löschen",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Löscht den Shader Cache der Anwendung",
|
||||
"GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC Verzeichnis öffnen",
|
||||
@ -109,21 +109,21 @@
|
||||
"SettingsTabSystemSystemLanguageTraditionalChinese": "Traditionelles Chinesisch",
|
||||
"SettingsTabSystemSystemTimeZone": "System Zeitzone:",
|
||||
"SettingsTabSystemSystemTime": "System Zeit:",
|
||||
"SettingsTabSystemEnableVsync": "Aktiviere VSync",
|
||||
"SettingsTabSystemEnablePptc": "Aktiviere PPTC Cache (Profiled presistent translastion cache)",
|
||||
"SettingsTabSystemEnableFsIntegrityChecks": "Aktiviere die FS Integritätsprüfung",
|
||||
"SettingsTabSystemEnableVsync": "VSync",
|
||||
"SettingsTabSystemEnablePptc": "PPTC Cache (Profiled Persistent Translation Cache)",
|
||||
"SettingsTabSystemEnableFsIntegrityChecks": "FS Integritätsprüfung",
|
||||
"SettingsTabSystemAudioBackend": "Audio-Backend:",
|
||||
"SettingsTabSystemAudioBackendDummy": "Dummy",
|
||||
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
|
||||
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
|
||||
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
||||
"SettingsTabSystemHacks": "Hacks",
|
||||
"SettingsTabSystemHacksNote": " (Können Fehler verursachen)",
|
||||
"SettingsTabSystemHacksNote": " (Kann Fehler verursachen)",
|
||||
"SettingsTabSystemExpandDramSize": "Erweitere DRAM Größe auf 6GB",
|
||||
"SettingsTabSystemIgnoreMissingServices": "Ignoriere fehlende Dienste",
|
||||
"SettingsTabGraphics": "Grafik",
|
||||
"SettingsTabGraphicsAPI": "Grafik-API",
|
||||
"SettingsTabGraphicsEnableShaderCache": "Aktiviere den Shader Cache",
|
||||
"SettingsTabGraphicsEnableShaderCache": "Shader Cache",
|
||||
"SettingsTabGraphicsAnisotropicFiltering": "Anisotrope Filterung:",
|
||||
"SettingsTabGraphicsAnisotropicFilteringAuto": "Auto",
|
||||
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
|
||||
@ -185,9 +185,9 @@
|
||||
"ControllerSettingsControllerType": "Controller Typ",
|
||||
"ControllerSettingsControllerTypeHandheld": "Handheld",
|
||||
"ControllerSettingsControllerTypeProController": "Pro Controller",
|
||||
"ControllerSettingsControllerTypeJoyConPair": "JoyCon Paar",
|
||||
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon Links",
|
||||
"ControllerSettingsControllerTypeJoyConRight": "JoyCon Rechts",
|
||||
"ControllerSettingsControllerTypeJoyConPair": "Joy-Con Paar",
|
||||
"ControllerSettingsControllerTypeJoyConLeft": "Joy-Con Links",
|
||||
"ControllerSettingsControllerTypeJoyConRight": "Joy-Con Rechts",
|
||||
"ControllerSettingsProfile": "Profil",
|
||||
"ControllerSettingsProfileDefault": "Default",
|
||||
"ControllerSettingsLoad": "Laden",
|
||||
@ -212,8 +212,8 @@
|
||||
"ControllerSettingsLStickLeft": "Links",
|
||||
"ControllerSettingsLStickRight": "Rechts",
|
||||
"ControllerSettingsLStickStick": "Analogstick",
|
||||
"ControllerSettingsLStickInvertXAxis": "Invertiert X-Achse",
|
||||
"ControllerSettingsLStickInvertYAxis": "Invertiert Y-Achse",
|
||||
"ControllerSettingsLStickInvertXAxis": "X-Achse invertieren",
|
||||
"ControllerSettingsLStickInvertYAxis": "Y-Achse invertieren",
|
||||
"ControllerSettingsLStickDeadzone": "Deadzone:",
|
||||
"ControllerSettingsRStick": "Rechter Analogstick",
|
||||
"ControllerSettingsRStickButton": "R3",
|
||||
@ -222,8 +222,8 @@
|
||||
"ControllerSettingsRStickLeft": "Links",
|
||||
"ControllerSettingsRStickRight": "Rechts",
|
||||
"ControllerSettingsRStickStick": "Analogstick",
|
||||
"ControllerSettingsRStickInvertXAxis": "Invertiert X-Achse",
|
||||
"ControllerSettingsRStickInvertYAxis": "Invertiert Y-Achse",
|
||||
"ControllerSettingsRStickInvertXAxis": "X-Achse invertieren",
|
||||
"ControllerSettingsRStickInvertYAxis": "Y-Achse invertieren",
|
||||
"ControllerSettingsRStickDeadzone": "Deadzone:",
|
||||
"ControllerSettingsTriggersLeft": "Linker Trigger",
|
||||
"ControllerSettingsTriggersRight": "Rechter Trigger",
|
||||
@ -246,7 +246,7 @@
|
||||
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "CemuHook kompatible Bewegungssteuerung",
|
||||
"ControllerSettingsMotionControllerSlot": "Controller Slot:",
|
||||
"ControllerSettingsMotionMirrorInput": "Spiegele Eingabe",
|
||||
"ControllerSettingsMotionRightJoyConSlot": "Rechter JoyCon Slot:",
|
||||
"ControllerSettingsMotionRightJoyConSlot": "Rechter Joy-Con Slot:",
|
||||
"ControllerSettingsMotionServerHost": "Server Host:",
|
||||
"ControllerSettingsMotionGyroSensitivity": "Gyro Empfindlichkeit:",
|
||||
"ControllerSettingsMotionGyroDeadzone": "Gyro Deadzone:",
|
||||
@ -256,8 +256,8 @@
|
||||
"UserProfilesSaveProfileName": "Profilname speichern",
|
||||
"UserProfilesChangeProfileImage": "Profilbild ändern",
|
||||
"UserProfilesAvailableUserProfiles": "Verfügbare Profile:",
|
||||
"UserProfilesAddNewProfile": "Neues Profil hinzufügen",
|
||||
"UserProfilesDeleteSelectedProfile": "Ausgewähltes Profil löschen",
|
||||
"UserProfilesAddNewProfile": "Neues Profil",
|
||||
"UserProfilesDeleteSelectedProfile": "Profil löschen",
|
||||
"UserProfilesClose": "Schließen",
|
||||
"ProfileImageSelectionTitle": "Auswahl des Profilbildes",
|
||||
"ProfileImageSelectionHeader": "Wähle ein Profilbild aus",
|
||||
@ -281,17 +281,17 @@
|
||||
"MenuBarFileToolsHideUi": "Verstecke UI",
|
||||
"GameListContextMenuToggleFavorite": "Als Favoriten hinzufügen/entfernen",
|
||||
"GameListContextMenuToggleFavoriteToolTip": "Aktiviert den Favoriten-Status des Spiels",
|
||||
"SettingsTabGeneralTheme": "Thema",
|
||||
"SettingsTabGeneralThemeCustomTheme": "Verzeichnis für benutzerdefiniertes Thema",
|
||||
"SettingsTabGeneralTheme": "Design",
|
||||
"SettingsTabGeneralThemeCustomTheme": "Pfad für das benutzerdefinierte Design",
|
||||
"SettingsTabGeneralThemeBaseStyle": "Farbschema",
|
||||
"SettingsTabGeneralThemeBaseStyleDark": "Dunkel",
|
||||
"SettingsTabGeneralThemeBaseStyleLight": "Hell",
|
||||
"SettingsTabGeneralThemeEnableCustomTheme": "Benutzerdefiniertes Thema",
|
||||
"SettingsTabGeneralThemeEnableCustomTheme": "Design für die Emulator-Benutzeroberfläche",
|
||||
"ButtonBrowse": "Durchsuchen",
|
||||
"ControllerSettingsConfigureGeneral": "Konfigurieren",
|
||||
"ControllerSettingsRumble": "Vibration",
|
||||
"ControllerSettingsRumbleStrongMultiplier": "Starke Vibration - Multiplikator",
|
||||
"ControllerSettingsRumbleWeakMultiplier": "Schwache Vibration - Multiplikator",
|
||||
"ControllerSettingsRumbleStrongMultiplier": "Starker Vibrations-Multiplikator",
|
||||
"ControllerSettingsRumbleWeakMultiplier": "Schwacher Vibrations-Multiplikator",
|
||||
"DialogMessageSaveNotAvailableMessage": "Es existieren keine Speicherdaten für {0} [{1:x16}]",
|
||||
"DialogMessageSaveNotAvailableCreateSaveMessage": "Soll Ryujinx Speicherdaten für dieses Spiel erstellen?",
|
||||
"DialogConfirmationTitle": "Ryujinx - Bestätigung",
|
||||
@ -328,7 +328,7 @@
|
||||
"DialogUpdaterDirtyBuildMessage": "Inoffizielle Versionen von Ryujinx können nicht aktualisiert werden",
|
||||
"DialogUpdaterDirtyBuildSubMessage": "Lade Ryujinx bitte von hier herunter, um eine unterstützte Version zu erhalten: https://ryujinx.org/",
|
||||
"DialogRestartRequiredMessage": "Neustart erforderlich",
|
||||
"DialogThemeRestartMessage": "Das Thema wurde gespeichert. Ein Neustart ist erforderlich, um das Thema anzuwenden.",
|
||||
"DialogThemeRestartMessage": "Das Design wurde gespeichert. Ein Neustart ist erforderlich, um das Design anzuwenden.",
|
||||
"DialogThemeRestartSubMessage": "Jetzt neu starten?",
|
||||
"DialogFirmwareInstallEmbeddedMessage": "Die in diesem Spiel enthaltene Firmware installieren? (Firmware {0})",
|
||||
"DialogFirmwareInstallEmbeddedSuccessMessage": "Es wurde keine installierte Firmware gefunden, aber Ryujinx konnte die Firmware {0} aus dem bereitgestellten Spiel installieren.\nRyujinx wird nun gestartet.",
|
||||
@ -350,7 +350,7 @@
|
||||
"DialogProfileDeleteProfileTitle": "Profil löschen",
|
||||
"DialogProfileDeleteProfileMessage": "Diese Aktion kann nicht rückgängig gemacht werden. Wirklich fortfahren?",
|
||||
"DialogWarning": "Warnung",
|
||||
"DialogPPTCDeletionMessage": "Du bist dabei, den PPTC Cache zu löschen für :\n\n{0}\n\nWirklich fortfahren?",
|
||||
"DialogPPTCDeletionMessage": "Du bist dabei den PPTC für das folgende Spiel als ungültig zu markieren:\n\n{0}\n\nWirklich fortfahren?",
|
||||
"DialogPPTCDeletionErrorMessage": "Fehler bei der Löschung des PPTC Caches bei {0}: {1}",
|
||||
"DialogShaderDeletionMessage": "Du bist dabei, den Shader Cache zu löschen für :\n\n{0}\n\nWirklich fortfahren?",
|
||||
"DialogShaderDeletionErrorMessage": "Es ist ein Fehler bei der Löschung des Shader Caches bei {0}: {1} aufgetreten",
|
||||
@ -379,7 +379,7 @@
|
||||
"DialogSettingsBackendThreadingWarningTitle": "Warnung - Render Threading",
|
||||
"DialogSettingsBackendThreadingWarningMessage": "Ryujinx muss muss neu gestartet werden, damit die Änderungen wirksam werden. Abhängig von dem Betriebssystem muss möglicherweise das Multithreading des Treibers manuell deaktiviert werden, wenn Ryujinx verwendet wird.",
|
||||
"SettingsTabGraphicsFeaturesOptions": "Erweiterungen",
|
||||
"SettingsTabGraphicsBackendMultithreading": "Grafikbackend Multithreading:",
|
||||
"SettingsTabGraphicsBackendMultithreading": "Grafik-Backend Multithreading:",
|
||||
"CommonAuto": "Auto",
|
||||
"CommonOff": "Aus",
|
||||
"CommonOn": "An",
|
||||
@ -416,52 +416,52 @@
|
||||
"CommonFavorite": "Favoriten",
|
||||
"OrderAscending": "Aufsteigend",
|
||||
"OrderDescending": "Absteigend",
|
||||
"SettingsTabGraphicsFeatures": "Erweiterungen & Verbesserungen",
|
||||
"SettingsTabGraphicsFeatures": "Erweiterungen",
|
||||
"ErrorWindowTitle": "Fehler-Fenster",
|
||||
"ToggleDiscordTooltip": "Aktiviert/Deaktiviert Discord Rich Presence",
|
||||
"ToggleDiscordTooltip": "Zeige momentanes Spiel auf Discord",
|
||||
"AddGameDirBoxTooltip": "Gibt das Spielverzeichnis an, das der Liste hinzuzufügt wird",
|
||||
"AddGameDirTooltip": "Fügt ein neues Spielverzeichnis hinzu",
|
||||
"RemoveGameDirTooltip": "Entfernt das ausgewähltes Spielverzeichnis",
|
||||
"CustomThemeCheckTooltip": "Aktiviert/Deaktiviert die benutzerdefinierten Thema in dem GUI",
|
||||
"CustomThemePathTooltip": " Gibt das Verzeichnis zum benutzerdefinierten GUI Thema an",
|
||||
"CustomThemeBrowseTooltip": "Ermöglicht die Suche nach benutzerdefinierten GUI Thema",
|
||||
"DockModeToggleTooltip": "Aktiviert/Deaktiviert den Docked Mode",
|
||||
"CustomThemeCheckTooltip": "Verwende ein eigenes Design für die Emulator-Benutzeroberfläche",
|
||||
"CustomThemePathTooltip": "Gibt den Pfad zum Design für die Emulator-Benutzeroberfläche an",
|
||||
"CustomThemeBrowseTooltip": "Ermöglicht die Suche nach einem benutzerdefinierten Design für die Emulator-Benutzeroberfläche",
|
||||
"DockModeToggleTooltip": "Im gedockten Modus verhält sich das emulierte System wie eine Nintendo Switch im TV Modus. Dies verbessert die grafische Qualität der meisten Spiele. Umgekehrt führt die Deaktivierung dazu, dass sich das emulierte System wie eine Nintendo Switch im Handheld Modus verhält, was die Grafikqualität beeinträchtigt.\n\nKonfiguriere das Eingabegerät für Spieler 1, um im Docked Modus zu spielen; konfiguriere das Controllerprofil via der Handheld Option, wenn geplant wird den Handheld Modus zu nutzen.\n\nIm Zweifelsfall AN lassen.",
|
||||
"DirectKeyboardTooltip": "Aktiviert/Deaktiviert den \"Direkter Tastaturzugriff (HID) Unterstützung\" (Ermöglicht die Benutzung der Tastaur als Eingabegerät in Spielen)",
|
||||
"DirectMouseTooltip": "Aktiviert/Deaktiviert den \"Direkten Mauszugriff (HID) Unterstützung\" (Ermöglicht die Benutzung der Maus als Eingabegerät in Spielen)",
|
||||
"RegionTooltip": "Ändert die Systemregion",
|
||||
"LanguageTooltip": "Ändert die Systemsprache",
|
||||
"TimezoneTooltip": "Ändert die Systemzeitzone",
|
||||
"TimeTooltip": "Ändert die Systemzeit",
|
||||
"VSyncToggleTooltip": "Aktiviert/Deaktiviert die Vertikale Synchronisierung",
|
||||
"PptcToggleTooltip": "Aktiviert/Deaktiviert den PPTC",
|
||||
"FsIntegrityToggleTooltip": "Aktiviert/Deaktiviert die Integritätsprüfung der Spieldateien",
|
||||
"AudioBackendTooltip": "Ändert das Audio-Backend",
|
||||
"MemoryManagerTooltip": "Ändert wie der Gastspeicher abgebildet wird und wie auf ihn zugegriffen wird. Beinflusst die Leistung der emulierten CPU erheblich.",
|
||||
"VSyncToggleTooltip": "Vertikale Synchronisierung der emulierten Konsole. Diese Option ist ein Frame-Limiter für die meisten Spiele; die Deaktivierung kann dazu führen, dass Spiele mit höherer Geschwindigkeit laufen, Ladebildschirme länger benötigen oder hängen bleiben.\n\nKann beim Spielen mit einem frei wählbaren Hotkey ein- und ausgeschaltet werden.\n\nIm Zweifelsfall AN lassen.",
|
||||
"PptcToggleTooltip": "Speichert übersetzte JIT-Funktionen, sodass jene nicht jedes Mal übersetzt werden müssen, wenn das Spiel geladen wird.\n\nVerringert Stottern und die Zeit beim zweiten und den darauffolgenden Startvorgängen eines Spiels erheblich.\n\nIm Zweifelsfall AN lassen.",
|
||||
"FsIntegrityToggleTooltip": "Prüft beim Startvorgang auf beschädigte Dateien und zeigt bei beschädigten Dateien einen Hash-Fehler (Hash Error) im Log an.\n\nDiese Einstellung hat keinen Einfluss auf die Leistung und hilft bei der Fehlersuche.\n\nIm Zweifelsfall AN lassen.",
|
||||
"AudioBackendTooltip": "Ändert das Backend, das zum Rendern von Audio verwendet wird.\n\nSDL2 ist das bevorzugte Audio-Backend, OpenAL und SoundIO sind als Alternativen vorhanden. Dummy wird keinen Audio-Output haben.\n\nIm Zweifelsfall SDL2 auswählen.",
|
||||
"MemoryManagerTooltip": "Ändert wie der Gastspeicher abgebildet wird und wie auf ihn zugegriffen wird. Beinflusst die Leistung der emulierten CPU erheblich.\n\nIm Zweifelsfall Host ungeprüft auswählen.",
|
||||
"MemoryManagerSoftwareTooltip": "Verwendung einer Software-Seitentabelle für die Adressumsetzung. Höchste Genauigkeit, aber langsamste Leistung.",
|
||||
"MemoryManagerHostTooltip": "Direkte Zuordnung von Speicher im Host-Adressraum. Viel schnellere JIT-Kompilierung und Ausführung.",
|
||||
"MemoryManagerUnsafeTooltip": "Direkte Zuordnung des Speichers, aber keine Maskierung der Adresse innerhalb des Gastadressraums vor dem Zugriff. Schneller, aber auf Kosten der Sicherheit. Die Gastanwendung kann von überall in Ryujinx auf den Speicher zugreifen, daher sollte in diesem Modus nur Programme ausgeführt werden denen vertraut wird.",
|
||||
"DRamTooltip": "Erweitert den Speicher des emulierten Systems von 4 GB auf 6 GB",
|
||||
"IgnoreMissingServicesTooltip": "Aktiviert/Deaktiviert die 'Ignoriere fehlende Dienste' Option",
|
||||
"GraphicsBackendThreadingTooltip": "Aktiviert das Grafikbackend Multithreading",
|
||||
"GalThreadingTooltip": "Führt Grafikbackendbefehle auf einem zweiten Thread aus. Ermöglicht Multithreading bei der Shader Kompilierung zur Laufzeit, reduziert Stottern und verbessert die Leistung bei Treibern ohne eigene Multithreading Unterstützung. Geringfügig abweichende Spitzenleistung bei Treibern mit Multithreading. Ryujinx muss möglicherweise neu gestartet werden, um das in den Treiber integrierte Multithreading korrekt zu deaktivieren, oder es muss manuell getan werden, um die beste Leistung zu erzielen.",
|
||||
"ShaderCacheToggleTooltip": "Aktiviert/Deaktiviert Shader Cache",
|
||||
"DRamTooltip": "Erhöht den Arbeitsspeicher des emulierten Systems von 4 GB auf 6 GB.\n\nDies ist nur für Texturenpakete mit höherer Auflösung oder Mods mit 4K-Auflösung nützlich. Diese Option verbessert NICHT die Leistung.\n\nIm Zweifelsfall AUS lassen.",
|
||||
"IgnoreMissingServicesTooltip": "Durch diese Option werden nicht implementierte Dienste der Switch-Firmware ignoriert. Dies kann dabei helfen, Abstürze beim Starten bestimmter Spiele zu umgehen.\n\nIm Zweifelsfall AUS lassen.",
|
||||
"GraphicsBackendThreadingTooltip": "Führt Grafik-Backend Befehle auf einem zweiten Thread aus.\n\nDies beschleunigt die Shader-Kompilierung, reduziert Stottern und verbessert die Leistung auf GPU-Treibern ohne eigene Multithreading-Unterstützung. Geringfügig bessere Leistung bei Treibern mit Multithreading.\n\nIm Zweifelsfall auf AUTO stellen.",
|
||||
"GalThreadingTooltip": "Führt Grafik-Backend Befehle auf einem zweiten Thread aus.\n\nDies Beschleunigt die Shader-Kompilierung, reduziert Stottern und verbessert die Leistung auf GPU-Treibern ohne eigene Multithreading-Unterstützung. Geringfügig bessere Leistung bei Treibern mit Multithreading.\n\nIm Zweifelsfall auf auf AUTO stellen.",
|
||||
"ShaderCacheToggleTooltip": "Speichert einen persistenten Shader Cache, der das Stottern bei nachfolgenden Durchläufen reduziert.\n\nIm Zweifelsfall AN lassen.",
|
||||
"ResolutionScaleTooltip": "Wendet die Auflösungsskalierung auf anwendbare Render Ziele",
|
||||
"ResolutionScaleEntryTooltip": "Fließkomma Auflösungsskalierung, wie 1,5.\n Bei nicht ganzzahligen Werten ist die Wahrscheinlichkeit größer, dass Probleme entstehen, die auch zum Absturz führen können.",
|
||||
"AnisotropyTooltip": "Stufe der Anisotropen Filterung (Auf Auto setzen, um den vom Spiel geforderten Wert zu verwenden)",
|
||||
"AspectRatioTooltip": "Auf das Renderer-Fenster angewandtes Seitenverhältnis.",
|
||||
"ShaderDumpPathTooltip": "Grafik-Shader-Dump-Pfad",
|
||||
"FileLogTooltip": "Aktiviert/Deaktiviert die Erstellung und Speicherung eines Logs",
|
||||
"StubLogTooltip": "Aktiviert die Ausgabe von Stub-Logs in der Konsole",
|
||||
"InfoLogTooltip": "Aktiviert die Ausgabe von Info-Logs in der Konsole",
|
||||
"WarnLogTooltip": "Aktiviert die Ausgabe von Warn-Logs in der Konsole",
|
||||
"TraceLogTooltip": "Aktiviert die Ausgabe von Trace-Log in der Konsole",
|
||||
"ErrorLogTooltip": "Aktiviert die Ausgabe von Fehler-Logs in der Konsole",
|
||||
"GuestLogTooltip": "Aktiviert die Ausgabe von Gast-Logs in der Konsole",
|
||||
"FileAccessLogTooltip": "Aktiviert die Ausgabe von FS-Zugriff-Logs in der Konsole",
|
||||
"FileLogTooltip": "Speichert die Konsolenausgabe in einer Log-Datei auf der Festplatte. Hat keinen Einfluss auf die Leistung.",
|
||||
"StubLogTooltip": "Ausgabe von Stub-Logs in der Konsole. Hat keinen Einfluss auf die Leistung.",
|
||||
"InfoLogTooltip": "Ausgabe von Info-Logs in der Konsole. Hat keinen Einfluss auf die Leistung.",
|
||||
"WarnLogTooltip": "Ausgabe von Warn-Logs in der Konsole. Hat keinen Einfluss auf die Leistung.",
|
||||
"TraceLogTooltip": "Ausgabe von Trace-Log in der Konsole. Hat keinen Einfluss auf die Leistung.",
|
||||
"ErrorLogTooltip": "Ausgabe von Fehler-Logs in der Konsole. Hat keinen Einfluss auf die Leistung.",
|
||||
"GuestLogTooltip": "Ausgabe von Gast-Logs in der Konsole. Hat keinen Einfluss auf die Leistung.",
|
||||
"FileAccessLogTooltip": "Ausgabe von FS-Zugriff-Logs in der Konsole.",
|
||||
"FSAccessLogModeTooltip": "Aktiviert die Ausgabe des FS-Zugriff-Logs in der Konsole. Mögliche Modi sind 0-3",
|
||||
"DeveloperOptionTooltip": "Mit Vorsicht verwenden",
|
||||
"OpenGlLogLevel": "Erfordert die Aktivierung der entsprechenden Log-Level",
|
||||
"DebugLogTooltip": "Aktiviert das Dokumentierern von Debug-Protokollmeldungen",
|
||||
"DebugLogTooltip": "Ausgabe von Debug-Logs in der Konsole.\n\nVerwende diese Option nur auf ausdrückliche Anweisung von Ryujinx Entwicklern, da sie das Lesen der Protokolle erschwert und die Leistung des Emulators verschlechtert.",
|
||||
"LoadApplicationFileTooltip": "Öffnet die Dateiauswahl um Datei zu laden, welche mit der Switch kompatibel ist",
|
||||
"LoadApplicationFolderTooltip": "Öffnet die Dateiauswahl um ein Spiel zu laden, welches mit der Switch kompatibel ist",
|
||||
"OpenRyujinxFolderTooltip": "Öffnet den Ordner, der das Ryujinx Dateisystem enthält",
|
||||
@ -478,8 +478,8 @@
|
||||
"AboutRyujinxContributorsButtonHeader": "Alle Mitwirkenden anzeigen",
|
||||
"SettingsTabSystemAudioVolume" : "Lautstärke: ",
|
||||
"AudioVolumeTooltip": "Ändert die Lautstärke",
|
||||
"SettingsTabSystemEnableInternetAccess": "Aktiviert den Gast-Internet-Zugang",
|
||||
"EnableInternetAccessTooltip": "Aktiviert den Gast-Internet-Zugang. Die Anwendung verhält sich so, als ob die emulierte Switch-Konsole mit dem Internet verbunden wäre. Beachte, dass in einigen Fällen Anwendungen auch bei deaktivierter Option auf das Internet zugreifen können",
|
||||
"SettingsTabSystemEnableInternetAccess": "Gast-Internet-Zugang/LAN Modus",
|
||||
"EnableInternetAccessTooltip": "Erlaubt es der emulierten Anwendung sich mit dem Internet zu verbinden.\n\nSpiele die den LAN-Modus unterstützen, ermöglichen es Ryujinx sich sowohl mit anderen Ryujinx-Systemen, als auch mit offiziellen Nintendo Switch Konsolen zu verbinden. Allerdings nur, wenn diese Option aktiviert ist und die Systeme mit demselben lokalen Netzwerk verbunden sind.\n\nDies erlaubt KEINE Verbindung zu Nintendo-Servern. Kann bei bestimmten Spielen die versuchen sich mit dem Internet zu verbinden zum Absturz führen.\n\nIm Zweifelsfall AUS lassen",
|
||||
"GameListContextMenuManageCheatToolTip": "Öffnet den Cheat-Manager",
|
||||
"GameListContextMenuManageCheat": "Cheats verwalten",
|
||||
"ControllerSettingsStickRange": "Bereich:",
|
||||
@ -491,11 +491,11 @@
|
||||
"SettingsTabNetworkConnection": "Netwerkverbindung",
|
||||
"SettingsTabCpuCache": "CPU-Cache",
|
||||
"SettingsTabCpuMemory": "CPU-Speicher",
|
||||
"DialogUpdaterFlatpakNotSupportedMessage": "Bitte Aktualisiere Ryujinx mit FlatHub",
|
||||
"DialogUpdaterFlatpakNotSupportedMessage": "Bitte aktualisiere Ryujinx mit FlatHub",
|
||||
"UpdaterDisabledWarningTitle": "Updater deaktiviert!",
|
||||
"GameListContextMenuOpenSdModsDirectory": "Atmosphere-Mod-Verzeichnis öffnen",
|
||||
"GameListContextMenuOpenSdModsDirectoryToolTip": "Öffnet das alternative SD-Karten-Atmosphere-Verzeichnis, das die Mods der Anwendung enthält",
|
||||
"ControllerSettingsRotate90": "Rotiert um 90°",
|
||||
"GameListContextMenuOpenSdModsDirectoryToolTip": "Öffnet das alternative SD-Karten-Atmosphere-Verzeichnis, das die Mods der Anwendung enthält. Dieser Ordner ist nützlich für Mods, die für einen gemoddete Switch erstellt worden sind.",
|
||||
"ControllerSettingsRotate90": "Um 90° rotieren",
|
||||
"IconSize": "Cover Größe",
|
||||
"IconSizeTooltip": "Ändert die Größe der Spiel-Cover",
|
||||
"MenuBarOptionsShowConsole": "Zeige Konsole",
|
||||
@ -546,17 +546,47 @@
|
||||
"RyujinxUpdater": "Ryujinx - Updater",
|
||||
"SettingsTabHotkeys": "Tastatur Hotkeys",
|
||||
"SettingsTabHotkeysHotkeys": "Tastatur Hotkeys",
|
||||
"SettingsTabHotkeysToggleVsyncHotkey": "Aktiviert/Deaktiviert VSync:",
|
||||
"SettingsTabHotkeysToggleVsyncHotkey": "VSync:",
|
||||
"SettingsTabHotkeysScreenshotHotkey": "Screenshot:",
|
||||
"SettingsTabHotkeysShowUiHotkey": "Zeige UI:",
|
||||
"SettingsTabHotkeysPauseHotkey": "Pausieren:",
|
||||
"SettingsTabHotkeysToggleMuteHotkey": "Stummschalten:",
|
||||
"ControllerMotionTitle": "Bewegungssteuerung - Einstellungen",
|
||||
"ControllerRumbleTitle": "Vibration - Einstellungen",
|
||||
"SettingsSelectThemeFileDialogTitle" : "Wähle ein benutzerdefiniertes Thema",
|
||||
"SettingsXamlThemeFile" : "Xaml Thema-Datei",
|
||||
"SettingsTabGraphicsBackend" : "Grafik-Backend",
|
||||
"GraphicsBackendTooltip" : "Ändert das Grafik-Backend",
|
||||
"SettingsSelectThemeFileDialogTitle" : "Wähle ein Design für die Emulator-Benutzeroberfläche",
|
||||
"SettingsXamlThemeFile" : "Xaml Design-Datei",
|
||||
"AvatarWindowTitle": "Profile verwalten - Avatar",
|
||||
"Amiibo": "Amiibo",
|
||||
"Unknown": "Unbekannt",
|
||||
"Usage": "Nutzung",
|
||||
"Writable": "Beschreibbar",
|
||||
"SelectDlcDialogTitle": "DLC-Dateien auswählen",
|
||||
"SelectUpdateDialogTitle": "Update-Datei auswählen",
|
||||
"UserProfileWindowTitle": "Benutzerprofile verwalten",
|
||||
"CheatWindowTitle": "Spiel-Cheats verwalten",
|
||||
"DlcWindowTitle": "Spiel-DLC verwalten",
|
||||
"UpdateWindowTitle": "Spiel-Updates verwalten",
|
||||
"CheatWindowHeading": "Cheats verfügbar für {0} [{1}]",
|
||||
"DlcWindowHeading": "DLC verfügbar für {0} [{1}]",
|
||||
"UserProfilesEditProfile": "Profil bearbeiten",
|
||||
"Cancel": "Abbrechen",
|
||||
"Save": "Speichern",
|
||||
"Discard": "Verwerfen",
|
||||
"UserProfilesSetProfileImage": "Profilbild einrichten",
|
||||
"UserProfileEmptyNameError": "Name ist erforderlich",
|
||||
"UserProfileNoImageError": "Bitte ein Profilbild auswählen",
|
||||
"GameUpdateWindowHeading": "Update verfügbar für {0} [{1}]",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Auflösung erhöhen:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Auflösung vermindern:"
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Auflösung verringern:",
|
||||
"UserProfilesName": "Name:",
|
||||
"UserProfilesUserId" : "Benutzer Id:",
|
||||
"SettingsTabGraphicsBackend": "Grafik-Backend:",
|
||||
"SettingsTabGraphicsBackendTooltip": "Verwendendetes Grafik-Backend",
|
||||
"SettingsEnableTextureRecompression": "Textur-Rekompression",
|
||||
"SettingsEnableTextureRecompressionTooltip": "Komprimiert bestimmte Texturen, um den VRAM-Verbrauch zu reduzieren.\n\nEmpfohlen für die Verwendung von GPUs, die weniger als 4 GB VRAM haben.\n\nIm Zweifelsfall AUS lassen",
|
||||
"SettingsTabGraphicsPreferredGpu": "Bevorzugte GPU:",
|
||||
"SettingsTabGraphicsPreferredGpuTooltip": "Wähle die Grafikkarte aus, die mit dem Vulkan Grafik-Backend verwendet werden soll.\n\nDies hat keinen Einfluss auf die GPU die OpenGL verwendet.\n\nIm Zweifelsfall die als \"dGPU\" gekennzeichnete GPU auswählen. Diese Einstellung unberührt lassen, wenn keine zur Auswahl steht.",
|
||||
"SettingsAppRequiredRestartMessage": "Ein Neustart von Ryujinx ist erforderlich",
|
||||
"SettingsGpuBackendRestartMessage": "Das Grafik-Backend oder die Grafikkarteneinstellungen wurden geändert. Ein Neustart ist erforderlich um diese Einstellungen anzuwenden.",
|
||||
"SettingsGpuBackendRestartSubMessage": "Ryujinx jetzt neu starten?"
|
||||
}
|
||||
|
@ -52,8 +52,8 @@
|
||||
"GameListContextMenuOpenModsDirectory": "Modディレクトリを開く",
|
||||
"GameListContextMenuOpenModsDirectoryToolTip": "アプリケーションの Mod データを格納するディレクトリを開きます",
|
||||
"GameListContextMenuCacheManagement": "キャッシュ管理",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "PPTC キャッシュを破棄",
|
||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "アプリケーションの PPTC キャッシュを破棄します",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "PPTC を再構築",
|
||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "次回のゲーム起動時に PPTC を再構築します",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCache": "シェーダキャッシュを破棄",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "アプリケーションのシェーダキャッシュを破棄します",
|
||||
"GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC ディレクトリを開く",
|
||||
@ -121,9 +121,9 @@
|
||||
"SettingsTabSystemHacksNote": " (挙動が不安定になる可能性があります)",
|
||||
"SettingsTabSystemExpandDramSize": "DRAMサイズを6GBに拡大",
|
||||
"SettingsTabSystemIgnoreMissingServices": "未実装サービスを無視",
|
||||
"SettingsTabGraphics": "グラフィクス",
|
||||
"SettingsTabGraphicsEnhancements": "拡張",
|
||||
"SettingsTabGraphicsEnableShaderCache": "シェーダキャッシュ",
|
||||
"SettingsTabGraphics": "グラフィックス",
|
||||
"SettingsTabGraphicsAPI": "グラフィックスAPI",
|
||||
"SettingsTabGraphicsEnableShaderCache": "シェーダキャッシュを有効",
|
||||
"SettingsTabGraphicsAnisotropicFiltering": "異方性フィルタリング:",
|
||||
"SettingsTabGraphicsAnisotropicFilteringAuto": "自動",
|
||||
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
|
||||
@ -144,7 +144,7 @@
|
||||
"SettingsTabGraphicsAspectRatio32x9": "32:9",
|
||||
"SettingsTabGraphicsAspectRatioStretch": "ウインドウサイズに合わせる",
|
||||
"SettingsTabGraphicsDeveloperOptions": "開発者向けオプション",
|
||||
"SettingsTabGraphicsShaderDumpPath": "グラフィクス シェーダダンプパス:",
|
||||
"SettingsTabGraphicsShaderDumpPath": "グラフィックス シェーダダンプパス:",
|
||||
"SettingsTabLogging": "ロギング",
|
||||
"SettingsTabLoggingLogging": "ロギング",
|
||||
"SettingsTabLoggingEnableLoggingToFile": "ファイルへのロギングを有効",
|
||||
@ -350,7 +350,7 @@
|
||||
"DialogProfileDeleteProfileTitle": "プロファイルを削除中",
|
||||
"DialogProfileDeleteProfileMessage": "このアクションは元に戻せません. 本当に続けてよろしいですか?",
|
||||
"DialogWarning": "警告",
|
||||
"DialogPPTCDeletionMessage": "PPTC キャッシュを破棄しようとしています:\n\n{0}\n\n実行してよろしいですか?",
|
||||
"DialogPPTCDeletionMessage": "次回起動時に PPTC を再構築します:\n\n{0}\n\n実行してよろしいですか?",
|
||||
"DialogPPTCDeletionErrorMessage": "PPTC キャッシュ破棄エラー {0}: {1}",
|
||||
"DialogShaderDeletionMessage": "シェーダキャッシュを破棄しようとしています:\n\n{0}\n\n実行してよろしいですか?",
|
||||
"DialogShaderDeletionErrorMessage": "シェーダキャッシュ破棄エラー {0}: {1}",
|
||||
@ -379,7 +379,7 @@
|
||||
"DialogSettingsBackendThreadingWarningTitle": "警告 - バックエンドスレッディング",
|
||||
"DialogSettingsBackendThreadingWarningMessage": "このオプションの変更を完全に適用するには Ryujinx の再起動が必要です. プラットフォームによっては, Ryujinx のものを使用する前に手動でドライバ自身のマルチスレッディングを無効にする必要があるかもしれません.",
|
||||
"SettingsTabGraphicsFeaturesOptions": "機能",
|
||||
"SettingsTabGraphicsBackendMultithreading": "グラフィクスバックエンドのマルチスレッド実行:",
|
||||
"SettingsTabGraphicsBackendMultithreading": "グラフィックスバックエンドのマルチスレッド実行:",
|
||||
"CommonAuto": "自動",
|
||||
"CommonOff": "オフ",
|
||||
"CommonOn": "オン",
|
||||
@ -425,7 +425,7 @@
|
||||
"CustomThemeCheckTooltip": "エミュレータのメニュー外観を変更するためカスタム Avalonia テーマを使用します",
|
||||
"CustomThemePathTooltip": "カスタム GUI テーマのパスです",
|
||||
"CustomThemeBrowseTooltip": "カスタム GUI テーマを参照します",
|
||||
"DockModeToggleTooltip": "有効にすると,ドッキングされた Nintendo Switch をエミュレートします.多くのゲームではグラフィクス品質が向上します.\n無効にすると,携帯モードの Nintendo Switch をエミュレートします.グラフィクスの品質は低下します.\n\nドッキングモード有効ならプレイヤー1の,無効なら携帯の入力を設定してください.\n\nよくわからない場合はオンのままにしてください.",
|
||||
"DockModeToggleTooltip": "有効にすると,ドッキングされた Nintendo Switch をエミュレートします.多くのゲームではグラフィックス品質が向上します.\n無効にすると,携帯モードの Nintendo Switch をエミュレートします.グラフィックスの品質は低下します.\n\nドッキングモード有効ならプレイヤー1の,無効なら携帯の入力を設定してください.\n\nよくわからない場合はオンのままにしてください.",
|
||||
"DirectKeyboardTooltip": "キーボード直接アクセス (HID) に対応します. キーボードをテキスト入力デバイスとして使用できます.",
|
||||
"DirectMouseTooltip": "マウス直接アクセス (HID) に対応します. マウスをポインティングデバイスとして使用できます.",
|
||||
"RegionTooltip": "システムの地域を変更します",
|
||||
@ -442,14 +442,14 @@
|
||||
"MemoryManagerUnsafeTooltip": "メモリを直接マップしますが, アクセス前にゲストのアドレス空間内のアドレスをマスクしません. より高速になりますが, 安全性が犠牲になります. ゲストアプリケーションは Ryujinx のどこからでもメモリにアクセスできるので,このモードでは信頼できるプログラムだけを実行するようにしてください.",
|
||||
"DRamTooltip": "エミュレートされたシステムのメモリ容量を 4GB から 6GB に増加します.\n\n高解像度のテクスチャパックや 4K解像度の mod を使用する場合に有用です. パフォーマンスを改善するものではありません.\n\nよくわからない場合はオフのままにしてください.",
|
||||
"IgnoreMissingServicesTooltip": "未実装の Horizon OS サービスを無視します. 特定のゲームにおいて起動時のクラッシュを回避できる場合があります.\n\nよくわからない場合はオフのままにしてください.",
|
||||
"GraphicsBackendThreadingTooltip": "グラフィクスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.",
|
||||
"GalThreadingTooltip": "グラフィクスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.",
|
||||
"GraphicsBackendThreadingTooltip": "グラフィックスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.",
|
||||
"GalThreadingTooltip": "グラフィックスバックエンドのコマンドを別スレッドで実行します.\n\nシェーダのコンパイルを高速化し, 遅延を軽減し, マルチスレッド非対応の GPU ドライバにおいてパフォーマンスを改善します. マルチスレッド対応のドライバでも若干パフォーマンス改善が見られます.\n\nよくわからない場合は自動に設定してください.",
|
||||
"ShaderCacheToggleTooltip": "ディスクシェーダキャッシュをセーブし,次回以降の実行時遅延を軽減します.\n\nよくわからない場合はオンのままにしてください.",
|
||||
"ResolutionScaleTooltip": "レンダリングに適用される解像度の倍率です",
|
||||
"ResolutionScaleEntryTooltip": "1.5 のような整数でない倍率を指定すると,問題が発生したりクラッシュしたりする場合があります.",
|
||||
"AnisotropyTooltip": "異方性フィルタリングのレベルです (ゲームが要求する値を使用する場合は「自動」を設定してください)",
|
||||
"AspectRatioTooltip": "レンダリングに適用されるアスペクト比です.",
|
||||
"ShaderDumpPathTooltip": "グラフィクス シェーダダンプのパスです",
|
||||
"ShaderDumpPathTooltip": "グラフィックス シェーダダンプのパスです",
|
||||
"FileLogTooltip": "コンソール出力されるログをディスク上のログファイルにセーブします. パフォーマンスには影響を与えません.",
|
||||
"StubLogTooltip": "stub ログメッセージをコンソールに出力します. パフォーマンスには影響を与えません.",
|
||||
"InfoLogTooltip": "info ログメッセージをコンソールに出力します. パフォーマンスには影響を与えません.",
|
||||
@ -539,7 +539,7 @@
|
||||
"LoadingHeading": "ロード中: {0}",
|
||||
"CompilingPPTC": "PTC をコンパイル中",
|
||||
"CompilingShaders": "シェーダをコンパイル中",
|
||||
"AllKeyboards": "すべてキーボード",
|
||||
"AllKeyboards": "すべてのキーボード",
|
||||
"OpenFileDialogTitle": "開くファイルを選択",
|
||||
"OpenFolderDialogTitle": "展開されたゲームフォルダを選択",
|
||||
"AllSupportedFormats": "すべての対応フォーマット",
|
||||
@ -573,9 +573,20 @@
|
||||
"Save": "セーブ",
|
||||
"Discard": "破棄",
|
||||
"UserProfilesSetProfileImage": "プロファイル画像を設定",
|
||||
"UserProfileEmptyNameError": "名前が必要です",
|
||||
"UserProfileEmptyNameError": "名称が必要です",
|
||||
"UserProfileNoImageError": "プロファイル画像が必要です",
|
||||
"GameUpdateWindowHeading": "利用可能なアップデート {0} [{1}]",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "解像度を上げる:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "解像度を下げる:"
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "解像度を下げる:",
|
||||
"UserProfilesName": "名称:",
|
||||
"UserProfilesUserId" : "ユーザID:",
|
||||
"SettingsTabGraphicsBackend": "グラフィックスバックエンド",
|
||||
"SettingsTabGraphicsBackendTooltip": "使用するグラフィックスバックエンドです",
|
||||
"SettingsEnableTextureRecompression": "テクスチャの再圧縮を有効",
|
||||
"SettingsEnableTextureRecompressionTooltip": "VRAMの使用量を削減するためテクスチャを圧縮します.\n\nGPUのVRAMが4GB未満の場合は使用を推奨します.\n\nよくわからない場合はオフのままにしてください.",
|
||||
"SettingsTabGraphicsPreferredGpu": "優先使用するGPU",
|
||||
"SettingsTabGraphicsPreferredGpuTooltip": "Vulkanグラフィックスバックエンドで使用されるグラフィックスカードを選択します.\n\nOpenGLが使用するGPUには影響しません.\n\n不明な場合は, \"dGPU\" としてフラグが立っているGPUに設定します. ない場合はそのままにします.",
|
||||
"SettingsAppRequiredRestartMessage": "Ryujinx の再起動が必要です",
|
||||
"SettingsGpuBackendRestartMessage": "グラフィックスバックエンドまたはGPUの設定が変更されました. 変更を適用するには再起動する必要があります",
|
||||
"SettingsGpuBackendRestartSubMessage": "今すぐ再起動しますか?"
|
||||
}
|
||||
|
592
Ryujinx.Ava/Assets/Locales/pl_PL.json
Normal file
592
Ryujinx.Ava/Assets/Locales/pl_PL.json
Normal file
@ -0,0 +1,592 @@
|
||||
{
|
||||
"MenuBarFileOpenApplet": "Otwórz Aplet",
|
||||
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Otwórz aplet Mii Editor w trybie Indywidualnym",
|
||||
"SettingsTabInputDirectMouseAccess": "Bezpośredni Dostęp do Myszy",
|
||||
"SettingsTabSystemMemoryManagerMode": "Tryb Menedżera Pamięci:",
|
||||
"SettingsTabSystemMemoryManagerModeSoftware": "Software",
|
||||
"SettingsTabSystemMemoryManagerModeHost": "Host (szybko)",
|
||||
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Host Niesprawdzony (najszybciej, niebezpiecznie)",
|
||||
"MenuBarFile": "_Plik",
|
||||
"MenuBarFileOpenFromFile": "_Załaduj Aplikację z Pliku",
|
||||
"MenuBarFileOpenUnpacked": "Załaduj _Rozpakowaną Grę",
|
||||
"MenuBarFileOpenEmuFolder": "Otwórz Folder Ryujinx",
|
||||
"MenuBarFileOpenLogsFolder": "Otwórz Folder Logów",
|
||||
"MenuBarFileExit": "_Wyjdź",
|
||||
"MenuBarOptions": "Opcje",
|
||||
"MenuBarOptionsToggleFullscreen": "Przełącz Tryb Pełnoekranowy",
|
||||
"MenuBarOptionsStartGamesInFullscreen": "Uruchamiaj Gry w Trybie Pełnoekranowym",
|
||||
"MenuBarOptionsStopEmulation": "Zatrzymaj Emulację",
|
||||
"MenuBarOptionsSettings": "_Ustawienia",
|
||||
"MenuBarOptionsManageUserProfiles": "_Zarządzaj Profilami Użytkowników",
|
||||
"MenuBarActions": "_Akcje",
|
||||
"MenuBarOptionsSimulateWakeUpMessage": "Symuluj Wiadomość Budzenia",
|
||||
"MenuBarActionsScanAmiibo": "Skanuj Amiibo",
|
||||
"MenuBarTools": "_Narzędzia",
|
||||
"MenuBarToolsInstallFirmware": "Zainstaluj Firmware",
|
||||
"MenuBarFileToolsInstallFirmwareFromFile": "Zainstaluj Firmware z XCI lub ZIP",
|
||||
"MenuBarFileToolsInstallFirmwareFromDirectory": "Zainstaluj Firmware z Katalogu",
|
||||
"MenuBarHelp": "Pomoc",
|
||||
"MenuBarHelpCheckForUpdates": "Sprawdź Aktualizacje",
|
||||
"MenuBarHelpAbout": "O Aplikacji",
|
||||
"MenuSearch": "Szukaj...",
|
||||
"GameListHeaderFavorite": "Ulub",
|
||||
"GameListHeaderIcon": "Ikona",
|
||||
"GameListHeaderApplication": "Nazwa",
|
||||
"GameListHeaderDeveloper": "Deweloper",
|
||||
"GameListHeaderVersion": "Wersja",
|
||||
"GameListHeaderTimePlayed": "Czas Gry",
|
||||
"GameListHeaderLastPlayed": "Ostatnio Grane",
|
||||
"GameListHeaderFileExtension": "Rozsz. Pliku",
|
||||
"GameListHeaderFileSize": "Rozm. Pliku",
|
||||
"GameListHeaderPath": "Ścieżka",
|
||||
"GameListContextMenuOpenUserSaveDirectory": "Otwórz Katalog Zapisów Użytkownika",
|
||||
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Otwiera katalog, który zawiera Zapis Użytkownika Aplikacji",
|
||||
"GameListContextMenuOpenUserDeviceDirectory": "Otwórz Katalog Urządzeń Użytkownika",
|
||||
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Otwiera katalog, który zawiera Zapis Urządzenia Aplikacji",
|
||||
"GameListContextMenuOpenUserBcatDirectory": "Otwórz Katalog BCAT Użytkownika",
|
||||
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Otwiera katalog, który zawiera Zapis BCAT Aplikacji",
|
||||
"GameListContextMenuManageTitleUpdates": "Zarządzaj Aktualizacjami Tytułów",
|
||||
"GameListContextMenuManageTitleUpdatesToolTip": "Otwiera okno zarządzania Aktualizacjami Tytułu",
|
||||
"GameListContextMenuManageDlc": "Zarządzaj DLC",
|
||||
"GameListContextMenuManageDlcToolTip": "Otwiera okno zarządzania DLC",
|
||||
"GameListContextMenuOpenModsDirectory": "Otwórz Katalog Modów",
|
||||
"GameListContextMenuOpenModsDirectoryToolTip": "Otwiera katalog zawierający Mody Aplikacji",
|
||||
"GameListContextMenuCacheManagement": "Zarządzanie Cache",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "Dodaj Rekompilację PPTC do Kolejki",
|
||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "Zainicjuj Rekompilację PPTC przy następnym uruchomieniu gry",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCache": "Wyczyść Cache Shaderów",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Usuwa cache shaderów aplikacji",
|
||||
"GameListContextMenuCacheManagementOpenPptcDirectory": "Otwórz Katalog PPTC",
|
||||
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Otwiera katalog, który zawiera cache PPTC aplikacji",
|
||||
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Otwórz Katalog Cache Shaderów",
|
||||
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Otwiera katalog, który zawiera cache shaderów aplikacji",
|
||||
"GameListContextMenuExtractData": "Wyodrębnij Dane",
|
||||
"GameListContextMenuExtractDataExeFS": "ExeFS",
|
||||
"GameListContextMenuExtractDataExeFSToolTip": "Wyodrębnij sekcję ExeFS z bieżącej konfiguracji aplikacji (w tym aktualizacje)",
|
||||
"GameListContextMenuExtractDataRomFS": "RomFS",
|
||||
"GameListContextMenuExtractDataRomFSToolTip": "Wyodrębnij sekcję RomFS z bieżącej konfiguracji aplikacji (w tym aktualizacje)",
|
||||
"GameListContextMenuExtractDataLogo": "Logo",
|
||||
"GameListContextMenuExtractDataLogoToolTip": "Wyodrębnij sekcję Logo z bieżącej konfiguracji aplikacji (w tym aktualizacje)",
|
||||
"StatusBarGamesLoaded": "{0}/{1} Załadowane Gry",
|
||||
"StatusBarSystemVersion": "Wersja Systemu: {0}",
|
||||
"Settings": "Ustawienia",
|
||||
"SettingsTabGeneral": "Interfejs Użytkownika",
|
||||
"SettingsTabGeneralGeneral": "Ogólne",
|
||||
"SettingsTabGeneralEnableDiscordRichPresence": "Włącz Bogatą Obecność Discord",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Sprawdź Aktualizacje przy Uruchomieniu",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Pokaż Okno Dialogowe \"Potwierdzenia Wyjścia\"",
|
||||
"SettingsTabGeneralHideCursorOnIdle": "Ukryj Kursor Podczas Bezczynności",
|
||||
"SettingsTabGeneralGameDirectories": "Katalogi Gier",
|
||||
"SettingsTabGeneralAdd": "Dodaj",
|
||||
"SettingsTabGeneralRemove": "Usuń",
|
||||
"SettingsTabSystem": "System",
|
||||
"SettingsTabSystemCore": "Główne",
|
||||
"SettingsTabSystemSystemRegion": "Region Systemu:",
|
||||
"SettingsTabSystemSystemRegionJapan": "Japonia",
|
||||
"SettingsTabSystemSystemRegionUSA": "USA",
|
||||
"SettingsTabSystemSystemRegionEurope": "Europa",
|
||||
"SettingsTabSystemSystemRegionAustralia": "Australia",
|
||||
"SettingsTabSystemSystemRegionChina": "Chiny",
|
||||
"SettingsTabSystemSystemRegionKorea": "Korea",
|
||||
"SettingsTabSystemSystemRegionTaiwan": "Tajwan",
|
||||
"SettingsTabSystemSystemLanguage": "Język Systemu:",
|
||||
"SettingsTabSystemSystemLanguageJapanese": "Japoński",
|
||||
"SettingsTabSystemSystemLanguageAmericanEnglish": "Amerykański Angielski",
|
||||
"SettingsTabSystemSystemLanguageFrench": "Francuski",
|
||||
"SettingsTabSystemSystemLanguageGerman": "Niemiecki",
|
||||
"SettingsTabSystemSystemLanguageItalian": "Włoski",
|
||||
"SettingsTabSystemSystemLanguageSpanish": "Hiszpański",
|
||||
"SettingsTabSystemSystemLanguageChinese": "Chiński",
|
||||
"SettingsTabSystemSystemLanguageKorean": "Koreański",
|
||||
"SettingsTabSystemSystemLanguageDutch": "Holenderski",
|
||||
"SettingsTabSystemSystemLanguagePortuguese": "Portugalski",
|
||||
"SettingsTabSystemSystemLanguageRussian": "Rosyjski",
|
||||
"SettingsTabSystemSystemLanguageTaiwanese": "Tajwański",
|
||||
"SettingsTabSystemSystemLanguageBritishEnglish": "Brytyjski Angielski",
|
||||
"SettingsTabSystemSystemLanguageCanadianFrench": "Kanadyjski Francuski",
|
||||
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Hiszpański Latynoamerykański",
|
||||
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Chiński Uproszczony",
|
||||
"SettingsTabSystemSystemLanguageTraditionalChinese": "Chiński Tradycyjny",
|
||||
"SettingsTabSystemSystemTimeZone": "Strefa Czasowa Systemu:",
|
||||
"SettingsTabSystemSystemTime": "Czas Systemu:",
|
||||
"SettingsTabSystemEnableVsync": "VSync",
|
||||
"SettingsTabSystemEnablePptc": "PPTC (Profilowany Cache Trwałych Tłumaczeń)",
|
||||
"SettingsTabSystemEnableFsIntegrityChecks": "Kontrole Integralności Systemu Plików",
|
||||
"SettingsTabSystemAudioBackend": "Backend Dżwięku:",
|
||||
"SettingsTabSystemAudioBackendDummy": "Atrapa",
|
||||
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
|
||||
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
|
||||
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
||||
"SettingsTabSystemHacks": "Hacki",
|
||||
"SettingsTabSystemHacksNote": " (mogą powodować niestabilność)",
|
||||
"SettingsTabSystemExpandDramSize": "Rozszerz Rozmiar DRAM do 6 GB",
|
||||
"SettingsTabSystemIgnoreMissingServices": "Ignoruj Brakujące Usługi",
|
||||
"SettingsTabGraphics": "Grafika",
|
||||
"SettingsTabGraphicsAPI": "Graficzne API",
|
||||
"SettingsTabGraphicsEnableShaderCache": "Włącz Cache Shaderów",
|
||||
"SettingsTabGraphicsAnisotropicFiltering": "Filtrowanie Anizotropowe:",
|
||||
"SettingsTabGraphicsAnisotropicFilteringAuto": "Auto",
|
||||
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
|
||||
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
|
||||
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
|
||||
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
|
||||
"SettingsTabGraphicsResolutionScale": "Skala Rozdzielczości:",
|
||||
"SettingsTabGraphicsResolutionScaleCustom": "Niestandardowa (Niezalecane)",
|
||||
"SettingsTabGraphicsResolutionScaleNative": "Natywna (720p/1080p)",
|
||||
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
|
||||
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
|
||||
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
|
||||
"SettingsTabGraphicsAspectRatio": "Współczynnik Proporcji:",
|
||||
"SettingsTabGraphicsAspectRatio4x3": "4:3",
|
||||
"SettingsTabGraphicsAspectRatio16x9": "16:9",
|
||||
"SettingsTabGraphicsAspectRatio16x10": "16:10",
|
||||
"SettingsTabGraphicsAspectRatio21x9": "21:9",
|
||||
"SettingsTabGraphicsAspectRatio32x9": "32:9",
|
||||
"SettingsTabGraphicsAspectRatioStretch": "Rozciągnij do Okna",
|
||||
"SettingsTabGraphicsDeveloperOptions": "Opcje Programistyczne",
|
||||
"SettingsTabGraphicsShaderDumpPath": "Ścieżka Zrzutu Shaderów Grafiki:",
|
||||
"SettingsTabLogging": "Logowanie",
|
||||
"SettingsTabLoggingLogging": "Logowanie",
|
||||
"SettingsTabLoggingEnableLoggingToFile": "Włącz Logowanie do Pliku",
|
||||
"SettingsTabLoggingEnableStubLogs": "Wlącz Skróty Logów",
|
||||
"SettingsTabLoggingEnableInfoLogs": "Włącz Logi Informacyjne",
|
||||
"SettingsTabLoggingEnableWarningLogs": "Włącz Logi Ostrzeżeń",
|
||||
"SettingsTabLoggingEnableErrorLogs": "Włącz Logi Błędów",
|
||||
"SettingsTabLoggingEnableTraceLogs": "Włącz Logi Śledzenia",
|
||||
"SettingsTabLoggingEnableGuestLogs": "Włącz Logi Gości",
|
||||
"SettingsTabLoggingEnableFsAccessLogs": "Włącz Logi Dostępu do Systemu Plików",
|
||||
"SettingsTabLoggingFsGlobalAccessLogMode": "Tryb Globalnych Logów Systemu Plików:",
|
||||
"SettingsTabLoggingDeveloperOptions": "Opcje programistyczne (OSTRZEŻENIE: Zmniejszą wydajność)",
|
||||
"SettingsTabLoggingOpenglLogLevel": "Poziom Logów OpenGL:",
|
||||
"SettingsTabLoggingOpenglLogLevelNone": "Żadne",
|
||||
"SettingsTabLoggingOpenglLogLevelError": "Błędy",
|
||||
"SettingsTabLoggingOpenglLogLevelPerformance": "Spowolnienia",
|
||||
"SettingsTabLoggingOpenglLogLevelAll": "Wszystkie",
|
||||
"SettingsTabLoggingEnableDebugLogs": "Włącz Logi Debugowania",
|
||||
"SettingsTabInput": "Sterowanie",
|
||||
"SettingsTabInputEnableDockedMode": "Tryb Zadokowany",
|
||||
"SettingsTabInputDirectKeyboardAccess": "Bezpośredni Dostęp do Klawiatury",
|
||||
"SettingsButtonSave": "Zapisz",
|
||||
"SettingsButtonClose": "Zamknij",
|
||||
"SettingsButtonApply": "Zastosuj",
|
||||
"ControllerSettingsPlayer": "Gracz",
|
||||
"ControllerSettingsPlayer1": "Gracz 1",
|
||||
"ControllerSettingsPlayer2": "Gracz 2",
|
||||
"ControllerSettingsPlayer3": "Gracz 3",
|
||||
"ControllerSettingsPlayer4": "Gracz 4",
|
||||
"ControllerSettingsPlayer5": "Gracz 5",
|
||||
"ControllerSettingsPlayer6": "Gracz 6",
|
||||
"ControllerSettingsPlayer7": "Gracz 7",
|
||||
"ControllerSettingsPlayer8": "Gracz 8",
|
||||
"ControllerSettingsHandheld": "Przenośny",
|
||||
"ControllerSettingsInputDevice": "Urządzenie Wejściowe",
|
||||
"ControllerSettingsRefresh": "Odśwież",
|
||||
"ControllerSettingsDeviceDisabled": "Wyłączone",
|
||||
"ControllerSettingsControllerType": "Typ Kontrolera",
|
||||
"ControllerSettingsControllerTypeHandheld": "Przenośny",
|
||||
"ControllerSettingsControllerTypeProController": "Pro Controller",
|
||||
"ControllerSettingsControllerTypeJoyConPair": "Para JoyCon-ów",
|
||||
"ControllerSettingsControllerTypeJoyConLeft": "Lewy JoyCon",
|
||||
"ControllerSettingsControllerTypeJoyConRight": "Prawy JoyCon",
|
||||
"ControllerSettingsProfile": "Profil",
|
||||
"ControllerSettingsProfileDefault": "Domyślny",
|
||||
"ControllerSettingsLoad": "Wczytaj",
|
||||
"ControllerSettingsAdd": "Dodaj",
|
||||
"ControllerSettingsRemove": "Usuń",
|
||||
"ControllerSettingsButtons": "Przyciski",
|
||||
"ControllerSettingsButtonA": "A",
|
||||
"ControllerSettingsButtonB": "B",
|
||||
"ControllerSettingsButtonX": "X",
|
||||
"ControllerSettingsButtonY": "Y",
|
||||
"ControllerSettingsButtonPlus": "+",
|
||||
"ControllerSettingsButtonMinus": "-",
|
||||
"ControllerSettingsDPad": "Pad Kierunkowy",
|
||||
"ControllerSettingsDPadUp": "Góra",
|
||||
"ControllerSettingsDPadDown": "Dół",
|
||||
"ControllerSettingsDPadLeft": "Lewo",
|
||||
"ControllerSettingsDPadRight": "Prawo",
|
||||
"ControllerSettingsLStick": "Lewa Gałka",
|
||||
"ControllerSettingsLStickButton": "Przycisk",
|
||||
"ControllerSettingsLStickUp": "Góra",
|
||||
"ControllerSettingsLStickDown": "Dół",
|
||||
"ControllerSettingsLStickLeft": "Lewo",
|
||||
"ControllerSettingsLStickRight": "Prawo",
|
||||
"ControllerSettingsLStickStick": "Gałka",
|
||||
"ControllerSettingsLStickInvertXAxis": "Odwróć X Gałki",
|
||||
"ControllerSettingsLStickInvertYAxis": "Odwróć Y Gałki",
|
||||
"ControllerSettingsLStickDeadzone": "Deadzone:",
|
||||
"ControllerSettingsRStick": "Prawa Gałka",
|
||||
"ControllerSettingsRStickButton": "Przycisk",
|
||||
"ControllerSettingsRStickUp": "Góra",
|
||||
"ControllerSettingsRStickDown": "Dół",
|
||||
"ControllerSettingsRStickLeft": "Lewo",
|
||||
"ControllerSettingsRStickRight": "Prawo",
|
||||
"ControllerSettingsRStickStick": "Gałka",
|
||||
"ControllerSettingsRStickInvertXAxis": "Odwróć X Gałki",
|
||||
"ControllerSettingsRStickInvertYAxis": "Odwróć Y Gałki",
|
||||
"ControllerSettingsRStickDeadzone": "Deadzone:",
|
||||
"ControllerSettingsTriggersLeft": "Lewe Triggery",
|
||||
"ControllerSettingsTriggersRight": "Prawe Triggery",
|
||||
"ControllerSettingsTriggersButtonsLeft": "Lewe Przyciski Triggerów",
|
||||
"ControllerSettingsTriggersButtonsRight": "Prawe Przyciski Triggerów",
|
||||
"ControllerSettingsTriggers": "Triggery",
|
||||
"ControllerSettingsTriggerL": "L",
|
||||
"ControllerSettingsTriggerR": "R",
|
||||
"ControllerSettingsTriggerZL": "ZL",
|
||||
"ControllerSettingsTriggerZR": "ZR",
|
||||
"ControllerSettingsLeftSL": "SL",
|
||||
"ControllerSettingsLeftSR": "SR",
|
||||
"ControllerSettingsRightSL": "SL",
|
||||
"ControllerSettingsRightSR": "SR",
|
||||
"ControllerSettingsExtraButtonsLeft": "Lewe Przyciski",
|
||||
"ControllerSettingsExtraButtonsRight": "Prawe Przyciski",
|
||||
"ControllerSettingsMisc": "Różne",
|
||||
"ControllerSettingsTriggerThreshold": "Próg Triggerów:",
|
||||
"ControllerSettingsMotion": "Ruch",
|
||||
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Użyj ruchu zgodnego z CemuHook",
|
||||
"ControllerSettingsMotionControllerSlot": "Slot Kontrolera:",
|
||||
"ControllerSettingsMotionMirrorInput": "Odzwierciedlaj Sterowanie",
|
||||
"ControllerSettingsMotionRightJoyConSlot": "Prawy Slot JoyCon:",
|
||||
"ControllerSettingsMotionServerHost": "Host Serwera:",
|
||||
"ControllerSettingsMotionGyroSensitivity": "Czułość Żyroskopu:",
|
||||
"ControllerSettingsMotionGyroDeadzone": "Deadzone Żyroskopu:",
|
||||
"ControllerSettingsSave": "Zapisz",
|
||||
"ControllerSettingsClose": "Zamknij",
|
||||
"UserProfilesSelectedUserProfile": "Wybrany Profil Użytkownika:",
|
||||
"UserProfilesSaveProfileName": "Zapisz Nazwę Profilu",
|
||||
"UserProfilesChangeProfileImage": "Zmień Obraz Profilu",
|
||||
"UserProfilesAvailableUserProfiles": "Dostępne Profile Użytkowników:",
|
||||
"UserProfilesAddNewProfile": "Utwórz Profil",
|
||||
"UserProfilesDeleteSelectedProfile": "Usuń Zaznaczone",
|
||||
"UserProfilesClose": "Zamknij",
|
||||
"ProfileImageSelectionTitle": "Wybór Obrazu Profilu",
|
||||
"ProfileImageSelectionHeader": "Wybierz zdjęcie profilowe",
|
||||
"ProfileImageSelectionNote": "Możesz zaimportować niestandardowy obraz profilu lub wybrać awatar z firmware'u systemowego",
|
||||
"ProfileImageSelectionImportImage": "Importuj Plik Obrazu",
|
||||
"ProfileImageSelectionSelectAvatar": "Wybierz Awatar z Firmware'u",
|
||||
"InputDialogTitle": "Okno Dialogowe Wprowadzania",
|
||||
"InputDialogOk": "OK",
|
||||
"InputDialogCancel": "Anuluj",
|
||||
"InputDialogAddNewProfileTitle": "Wybierz Nazwę Profilu",
|
||||
"InputDialogAddNewProfileHeader": "Wprowadź Nazwę Profilu",
|
||||
"InputDialogAddNewProfileSubtext": "(Maksymalna Długość: {0})",
|
||||
"AvatarChoose": "Wybierz",
|
||||
"AvatarSetBackgroundColor": "Ustaw Kolor Tła",
|
||||
"AvatarClose": "Zamknij",
|
||||
"ControllerSettingsLoadProfileToolTip": "Załaduj Profil",
|
||||
"ControllerSettingsAddProfileToolTip": "Dodaj Profil",
|
||||
"ControllerSettingsRemoveProfileToolTip": "Usuń Profil",
|
||||
"ControllerSettingsSaveProfileToolTip": "Zapisz Profil",
|
||||
"MenuBarFileToolsTakeScreenshot": "Zrób Zrzut Ekranu",
|
||||
"MenuBarFileToolsHideUi": "Ukryj UI",
|
||||
"GameListContextMenuToggleFavorite": "Przełącz Ulubione",
|
||||
"GameListContextMenuToggleFavoriteToolTip": "Przełącz status Ulubionej Gry",
|
||||
"SettingsTabGeneralTheme": "Motyw",
|
||||
"SettingsTabGeneralThemeCustomTheme": "Ścieżka Niestandardowych Motywów",
|
||||
"SettingsTabGeneralThemeBaseStyle": "Styl Podstawowy",
|
||||
"SettingsTabGeneralThemeBaseStyleDark": "Ciemny",
|
||||
"SettingsTabGeneralThemeBaseStyleLight": "Jasny",
|
||||
"SettingsTabGeneralThemeEnableCustomTheme": "Włącz Niestandardowy Motyw",
|
||||
"ButtonBrowse": "Przeglądaj",
|
||||
"ControllerSettingsConfigureGeneral": "Konfiguruj",
|
||||
"ControllerSettingsRumble": "Wibracje",
|
||||
"ControllerSettingsRumbleStrongMultiplier": "Mocny Mnożnik Wibracji",
|
||||
"ControllerSettingsRumbleWeakMultiplier": "Słaby Mnożnik Wibracji",
|
||||
"DialogMessageSaveNotAvailableMessage": "Nie ma danych zapisu dla {0} [{1:x16}]",
|
||||
"DialogMessageSaveNotAvailableCreateSaveMessage": "Czy chcesz utworzyć dane zapisu dla tej gry?",
|
||||
"DialogConfirmationTitle": "Ryujinx - Potwierdzenie",
|
||||
"DialogUpdaterTitle": "Ryujinx - Aktualizator",
|
||||
"DialogErrorTitle": "Ryujinx - Błąd",
|
||||
"DialogWarningTitle": "Ryujinx - Uwaga",
|
||||
"DialogExitTitle": "Ryujinx - Wyjdź",
|
||||
"DialogErrorMessage": "Ryujinx napotkał błąd",
|
||||
"DialogExitMessage": "Czy na pewno chcesz zamknąć Ryujinx?",
|
||||
"DialogExitSubMessage": "Wszystkie niezapisane dane zostaną utracone!",
|
||||
"DialogMessageCreateSaveErrorMessage": "Wystąpił błąd podczas tworzenia określonych danych zapisu: {0}",
|
||||
"DialogMessageFindSaveErrorMessage": "Wystąpił błąd podczas znajdowania określonych danych zapisu: {0}",
|
||||
"FolderDialogExtractTitle": "Wybierz folder do rozpakowania",
|
||||
"DialogNcaExtractionMessage": "Wyodrębnianie sekcji {0} z {1}...",
|
||||
"DialogNcaExtractionTitle": "Ryujinx - Ekstraktor Sekcji NCA",
|
||||
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Niepowodzenie ekstrakcji. W wybranym pliku nie było głównego NCA.",
|
||||
"DialogNcaExtractionCheckLogErrorMessage": "Niepowodzenie ekstrakcji. Przeczytaj plik dziennika, aby uzyskać więcej informacji.",
|
||||
"DialogNcaExtractionSuccessMessage": "Ekstrakcja zakończona pomyślnie.",
|
||||
"DialogUpdaterConvertFailedMessage": "Nie udało się przekonwertować obecnej wersji Ryujinx.",
|
||||
"DialogUpdaterCancelUpdateMessage": "Anulowanie Aktualizacji!",
|
||||
"DialogUpdaterAlreadyOnLatestVersionMessage": "Używasz już najnowszej wersji Ryujinx!",
|
||||
"DialogUpdaterFailedToGetVersionMessage": "Wystąpił błąd podczas próby uzyskania informacji o wydaniu z Github Release. Może to być spowodowane nową wersją kompilowaną przez GitHub Actions. Spróbuj ponownie za kilka minut.",
|
||||
"DialogUpdaterConvertFailedGithubMessage": "Nie udało się przekonwertować otrzymanej wersji Ryujinx z Github Release.",
|
||||
"DialogUpdaterDownloadingMessage": "Pobieranie Aktualizacji...",
|
||||
"DialogUpdaterExtractionMessage": "Wypakowywanie Aktualizacji...",
|
||||
"DialogUpdaterRenamingMessage": "Zmiana Nazwy Aktualizacji...",
|
||||
"DialogUpdaterAddingFilesMessage": "Dodawanie Nowej Aktualizacji...",
|
||||
"DialogUpdaterCompleteMessage": "Aktualizacja Zakończona!",
|
||||
"DialogUpdaterRestartMessage": "Czy chcesz teraz zrestartować Ryujinx?",
|
||||
"DialogUpdaterArchNotSupportedMessage": "Nie używasz obsługiwanej architektury systemu!",
|
||||
"DialogUpdaterArchNotSupportedSubMessage": "(Obsługiwane są tylko systemy x64!)",
|
||||
"DialogUpdaterNoInternetMessage": "Nie masz połączenia z Internetem!",
|
||||
"DialogUpdaterNoInternetSubMessage": "Sprawdź, czy masz działające połączenie internetowe!",
|
||||
"DialogUpdaterDirtyBuildMessage": "Nie możesz zaktualizować Dirty wersji Ryujinx!",
|
||||
"DialogUpdaterDirtyBuildSubMessage": "Pobierz Ryujinx ze strony https://ryujinx.org/, jeśli szukasz obsługiwanej wersji.",
|
||||
"DialogRestartRequiredMessage": "Wymagane Ponowne Uruchomienie",
|
||||
"DialogThemeRestartMessage": "Motyw został zapisany. Aby zastosować motyw, konieczne jest ponowne uruchomienie.",
|
||||
"DialogThemeRestartSubMessage": "Czy chcesz uruchomić ponownie?",
|
||||
"DialogFirmwareInstallEmbeddedMessage": "Czy chcesz zainstalować firmware wbudowany w tę grę? (Firmware {0})",
|
||||
"DialogFirmwareInstallEmbeddedSuccessMessage": "Nie znaleziono zainstalowanego firmware'u, ale Ryujinx był w stanie zainstalować firmware {0} z dostarczonej gry.\n\nEmulator uruchomi się teraz.",
|
||||
"DialogFirmwareNoFirmwareInstalledMessage": "Brak Zainstalowanego Firmware'u",
|
||||
"DialogFirmwareInstalledMessage": "Firmware {0} został zainstalowany",
|
||||
"DialogOpenSettingsWindowLabel": "Otwórz Okno Ustawień",
|
||||
"DialogControllerAppletTitle": "Aplet Kontrolera",
|
||||
"DialogMessageDialogErrorExceptionMessage": "Błąd wyświetlania okna Dialogowego Wiadomości: {0}",
|
||||
"DialogSoftwareKeyboardErrorExceptionMessage": "Błąd wyświetlania Klawiatury Oprogramowania: {0}",
|
||||
"DialogErrorAppletErrorExceptionMessage": "Błąd wyświetlania okna Dialogowego ErrorApplet: {0}",
|
||||
"DialogUserErrorDialogMessage": "{0}: {1}",
|
||||
"DialogUserErrorDialogInfoMessage": "\nAby uzyskać więcej informacji o tym, jak naprawić ten błąd, zapoznaj się z naszym Przewodnikiem instalacji.",
|
||||
"DialogUserErrorDialogTitle": "Błąd Ryujinxa ({0})",
|
||||
"DialogAmiiboApiTitle": "API Amiibo",
|
||||
"DialogAmiiboApiFailFetchMessage": "Wystąpił błąd podczas pobierania informacji z API.",
|
||||
"DialogAmiiboApiConnectErrorMessage": "Nie można połączyć się z serwerem API Amiibo. Usługa może nie działać lub może być konieczne sprawdzenie, czy połączenie internetowe jest online.",
|
||||
"DialogProfileInvalidProfileErrorMessage": "Profil {0} jest niezgodny z bieżącym systemem konfiguracji sterowania.",
|
||||
"DialogProfileDefaultProfileOverwriteErrorMessage": "Profil Domyślny nie może zostać nadpisany",
|
||||
"DialogProfileDeleteProfileTitle": "Usuwanie Profilu",
|
||||
"DialogProfileDeleteProfileMessage": "Ta czynność jest nieodwracalna, czy na pewno chcesz kontynuować?",
|
||||
"DialogWarning": "Uwaga",
|
||||
"DialogPPTCDeletionMessage": "Masz zamiar umieścić w kolejce rekompilację PPTC przy następnym uruchomieniu:\n\n{0}\n\nCzy na pewno chcesz kontynuować?",
|
||||
"DialogPPTCDeletionErrorMessage": "Błąd czyszczenia cache PPTC w {0}: {1}",
|
||||
"DialogShaderDeletionMessage": "Zamierzasz usunąć cache Shaderów dla :\n\n{0}\n\nNa pewno chcesz kontynuować?",
|
||||
"DialogShaderDeletionErrorMessage": "Błąd czyszczenia cache Shaderów w {0}: {1}",
|
||||
"DialogRyujinxErrorMessage": "Ryujinx napotkał błąd",
|
||||
"DialogInvalidTitleIdErrorMessage": "Błąd UI: Wybrana gra nie miała prawidłowego ID tytułu",
|
||||
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "Nie znaleziono prawidłowego firmware'u systemowego w {0}.",
|
||||
"DialogFirmwareInstallerFirmwareInstallTitle": "Zainstaluj Firmware {0}",
|
||||
"DialogFirmwareInstallerFirmwareInstallMessage": "Wersja systemu {0} zostanie zainstalowana.",
|
||||
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nZastąpi to obecną wersję systemu {0}.",
|
||||
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nCzy chcesz kontynuować?",
|
||||
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Instalowanie firmware'u...",
|
||||
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Wersja systemu {0} została pomyślnie zainstalowana.",
|
||||
"DialogUserProfileDeletionWarningMessage": "Nie będzie innych profili do otwarcia, jeśli wybrany profil zostanie usunięty",
|
||||
"DialogUserProfileDeletionConfirmMessage": "Czy chcesz usunąć wybrany profil",
|
||||
"DialogControllerSettingsModifiedConfirmMessage": "Aktualne ustawienia kontrolera zostały zaktualizowane.",
|
||||
"DialogControllerSettingsModifiedConfirmSubMessage": "Czy chcesz zapisać?",
|
||||
"DialogDlcLoadNcaErrorMessage": "{0}. Błędny Plik: {1}",
|
||||
"DialogDlcNoDlcErrorMessage": "Określony plik nie zawiera DLC dla wybranego tytułu!",
|
||||
"DialogPerformanceCheckLoggingEnabledMessage": "Masz włączone rejestrowanie śledzenia, które jest przeznaczone tylko dla programistów.",
|
||||
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "Aby uzyskać optymalną wydajność, zaleca się wyłączenie rejestrowania śledzenia. Czy chcesz teraz wyłączyć rejestrowanie śledzenia?",
|
||||
"DialogPerformanceCheckShaderDumpEnabledMessage": "Masz włączone zrzucanie shaderów, które jest przeznaczone tylko dla programistów.",
|
||||
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "Aby uzyskać optymalną wydajność, zaleca się wyłączenie zrzucania shaderów. Czy chcesz teraz wyłączyć zrzucanie shaderów?",
|
||||
"DialogLoadAppGameAlreadyLoadedMessage": "Gra została już załadowana",
|
||||
"DialogLoadAppGameAlreadyLoadedSubMessage": "Zatrzymaj emulację lub zamknij emulator przed uruchomieniem innej gry.",
|
||||
"DialogUpdateAddUpdateErrorMessage": "Określony plik nie zawiera aktualizacji dla wybranego tytułu!",
|
||||
"DialogSettingsBackendThreadingWarningTitle": "Ostrzeżenie — Wątki Backend",
|
||||
"DialogSettingsBackendThreadingWarningMessage": "Ryujinx musi zostać ponownie uruchomiony po zmianie tej opcji, aby działał w pełni. W zależności od platformy może być konieczne ręczne wyłączenie sterownika wielowątkowości podczas korzystania z Ryujinx.",
|
||||
"SettingsTabGraphicsFeaturesOptions": "Funkcje",
|
||||
"SettingsTabGraphicsBackendMultithreading": "Wielowątkowość Backendu Graficznego:",
|
||||
"CommonAuto": "Auto",
|
||||
"CommonOff": "Wyłączone",
|
||||
"CommonOn": "Włączone",
|
||||
"InputDialogYes": "Tak",
|
||||
"InputDialogNo": "Nie",
|
||||
"DialogProfileInvalidProfileNameErrorMessage": "Nazwa pliku zawiera nieprawidłowe znaki. Proszę spróbuj ponownie.",
|
||||
"MenuBarOptionsPauseEmulation": "Pauza",
|
||||
"MenuBarOptionsResumeEmulation": "Wznów",
|
||||
"AboutUrlTooltipMessage": "Kliknij, aby otworzyć stronę Ryujinx w domyślnej przeglądarce.",
|
||||
"AboutDisclaimerMessage": "Ryujinx nie jest w żaden sposób powiązany z Nintendo™,\nani z żadnym z jej partnerów.",
|
||||
"AboutAmiiboDisclaimerMessage": "AmiiboAPI (www.amiiboapi.com) jest używane\nw naszej emulacji Amiibo.",
|
||||
"AboutPatreonUrlTooltipMessage": "Kliknij, aby otworzyć stronę Patreon Ryujinx w domyślnej przeglądarce.",
|
||||
"AboutGithubUrlTooltipMessage": "Kliknij, aby otworzyć stronę GitHub Ryujinx w domyślnej przeglądarce.",
|
||||
"AboutDiscordUrlTooltipMessage": "Kliknij, aby otworzyć zaproszenie na serwer Discord Ryujinx w domyślnej przeglądarce.",
|
||||
"AboutTwitterUrlTooltipMessage": "Kliknij, aby otworzyć stronę Twitter Ryujinx w domyślnej przeglądarce.",
|
||||
"AboutRyujinxAboutTitle": "O Aplikacji:",
|
||||
"AboutRyujinxAboutContent": "Ryujinx to emulator Nintendo Switch™.\nWspieraj nas na Patreonie.\nOtrzymuj najnowsze wiadomości na naszym Twitterze lub Discordzie.\nDeweloperzy zainteresowani współpracą mogą dowiedzieć się więcej na naszym GitHubie lub Discordzie.",
|
||||
"AboutRyujinxMaintainersTitle": "Utrzymywany Przez:",
|
||||
"AboutRyujinxMaintainersContentTooltipMessage": "Kliknij, aby otworzyć stronę Współtwórcy w domyślnej przeglądarce.",
|
||||
"AboutRyujinxSupprtersTitle": "Wspierani na Patreonie Przez:",
|
||||
"AmiiboSeriesLabel": "Seria Amiibo",
|
||||
"AmiiboCharacterLabel": "Postać",
|
||||
"AmiiboScanButtonLabel": "Zeskanuj",
|
||||
"AmiiboOptionsShowAllLabel": "Pokaż Wszystkie Amiibo",
|
||||
"AmiiboOptionsUsRandomTagLabel": "Hack: Użyj losowego UUID tagu",
|
||||
"DlcManagerTableHeadingEnabledLabel": "Włączone",
|
||||
"DlcManagerTableHeadingTitleIdLabel": "ID Tytułu",
|
||||
"DlcManagerTableHeadingContainerPathLabel": "Ścieżka Kontenera",
|
||||
"DlcManagerTableHeadingFullPathLabel": "Pełna Ścieżka",
|
||||
"DlcManagerRemoveAllButton": "Usuń Wszystkie",
|
||||
"MenuBarOptionsChangeLanguage": "Zmień Język",
|
||||
"CommonSort": "Sortuj",
|
||||
"CommonShowNames": "Pokaż Nazwy",
|
||||
"CommonFavorite": "Ulubione",
|
||||
"OrderAscending": "Rosnąco",
|
||||
"OrderDescending": "Malejąco",
|
||||
"SettingsTabGraphicsFeatures": "Funkcje i Ulepszenia",
|
||||
"ErrorWindowTitle": "Okno Błędu",
|
||||
"ToggleDiscordTooltip": "Wybierz, czy chcesz wyświetlać Ryujinx w swojej \"aktualnie grane\" aktywności Discord",
|
||||
"AddGameDirBoxTooltip": "Wprowadź katalog gier aby dodać go do listy",
|
||||
"AddGameDirTooltip": "Dodaj katalog gier do listy",
|
||||
"RemoveGameDirTooltip": "Usuń wybrany katalog gier",
|
||||
"CustomThemeCheckTooltip": "Użyj niestandardowego motywu Avalonia dla GUI, aby zmienić wygląd menu emulatora",
|
||||
"CustomThemePathTooltip": "Ścieżka do niestandardowego motywu GUI",
|
||||
"CustomThemeBrowseTooltip": "Wyszukaj niestandardowy motyw GUI",
|
||||
"DockModeToggleTooltip": "Tryb Zadokowany sprawia, że emulowany system zachowuje się jak zadokowany Nintendo Switch. Poprawia to jakość grafiki w większości gier. I odwrotnie, wyłączenie tej opcji sprawi, że emulowany system będzie zachowywał się jak przenośny Nintendo Switch, zmniejszając jakość grafiki.\n\nSkonfiguruj sterowanie gracza 1, jeśli planujesz używać trybu Zadokowanego; Skonfiguruj sterowanie przenośne, jeśli planujesz używać trybu przenośnego.\n\nPozostaw WŁĄCZONY, jeśli nie masz pewności.",
|
||||
"DirectKeyboardTooltip": "Obsługa bezpośredniego dostępu klawiatury (HID). Zapewnia dostęp gier do klawiatury jako urządzenia do wprowadzania tekstu.",
|
||||
"DirectMouseTooltip": "Obsługa bezpośredniego dostępu myszy (HID). Zapewnia grom dostęp do myszy jako urządzenia wskazującego.",
|
||||
"RegionTooltip": "Zmień Region Systemu",
|
||||
"LanguageTooltip": "Zmień Język Systemu",
|
||||
"TimezoneTooltip": "Zmień Strefę Czasową Systemu",
|
||||
"TimeTooltip": "Zmień Czas Systemu",
|
||||
"VSyncToggleTooltip": "Pionowa synchronizacja emulowanej konsoli. Zasadniczo ogranicznik klatek dla większości gier; wyłączenie jej może spowodować, że gry będą działać z większą szybkością, ekrany wczytywania wydłużą się lub nawet utkną.\n\nMoże być przełączana w grze za pomocą preferowanego skrótu klawiszowego. Zalecamy to zrobić, jeśli planujesz ją wyłączyć.\n\nW razie wątpliwości pozostaw WŁĄCZONĄ",
|
||||
"PptcToggleTooltip": "Zapisuje przetłumaczone funkcje JIT, dzięki czemu nie muszą być tłumaczone za każdym razem, gdy gra się ładuje.\n\nZmniejsza zacinanie się i znacznie przyspiesza uruchamianie po pierwszym uruchomieniu gry.\n\nJeśli nie masz pewności, pozostaw WŁĄCZONE",
|
||||
"FsIntegrityToggleTooltip": "Sprawdza pliki podczas uruchamiania gry i jeśli zostaną wykryte uszkodzone pliki, wyświetla w dzienniku błąd hash.\n\nNie ma wpływu na wydajność i ma pomóc w rozwiązywaniu problemów.\n\nPozostaw WŁĄCZONE, jeśli nie masz pewności.",
|
||||
"AudioBackendTooltip": "Zmienia backend używany do renderowania dźwięku.\n\nSDL2 jest preferowany, podczas gdy OpenAL i SoundIO są używane jako rezerwy. Dummy nie będzie odtwarzać dźwięku.\n\nW razie wątpliwości ustaw SDL2.",
|
||||
"MemoryManagerTooltip": "Zmień sposób mapowania i uzyskiwania dostępu do pamięci gości. Znacznie wpływa na wydajność emulowanego procesora.\n\nUstaw na HOST UNCHECKED, jeśli nie masz pewności.",
|
||||
"MemoryManagerSoftwareTooltip": "Użyj tabeli stron oprogramowania do translacji adresów. Najwyższa celność, ale najwolniejsza wydajność.",
|
||||
"MemoryManagerHostTooltip": "Bezpośrednio mapuj pamięć w przestrzeni adresowej hosta. Znacznie szybsza kompilacja i wykonanie JIT.",
|
||||
"MemoryManagerUnsafeTooltip": "Bezpośrednio mapuj pamięć, ale nie maskuj adresu w przestrzeni adresowej gościa przed uzyskaniem dostępu. Szybciej, ale kosztem bezpieczeństwa. Aplikacja gościa może uzyskać dostęp do pamięci z dowolnego miejsca w Ryujinx, więc w tym trybie uruchamiaj tylko programy, którym ufasz.",
|
||||
"DRamTooltip": "Zwiększa ilość pamięci w emulowanym systemie z 4 GB do 6 GB.\n\nJest to przydatne tylko w przypadku pakietów tekstur o wyższej rozdzielczości lub modów w rozdzielczości 4k. NIE poprawia wydajności.\n\nW razie wątpliwości pozostaw WYŁĄCZONE.",
|
||||
"IgnoreMissingServicesTooltip": "Ignoruje niezaimplementowane usługi Horizon OS. Może to pomóc w ominięciu awarii podczas uruchamiania niektórych gier.\n\nW razie wątpliwości pozostaw WYŁĄCZONE.",
|
||||
"GraphicsBackendThreadingTooltip": "Wykonuje polecenia backend'u graficznego w drugim wątku.\n\nPrzyspiesza kompilację shaderów, zmniejsza zacinanie się i poprawia wydajność sterowników GPU bez własnej obsługi wielowątkowości. Nieco lepsza wydajność w sterownikach z wielowątkowością.\n\nUstaw na AUTO, jeśli nie masz pewności.",
|
||||
"GalThreadingTooltip": "Wykonuje polecenia backend'u graficznego w drugim wątku.\n\nPrzyspiesza kompilację shaderów, zmniejsza zacinanie się i poprawia wydajność sterowników GPU bez własnej obsługi wielowątkowości. Nieco lepsza wydajność w sterownikach z wielowątkowością.\n\nUstaw na AUTO, jeśli nie masz pewności.",
|
||||
"ShaderCacheToggleTooltip": "Zapisuje pamięć podręczną shaderów na dysku, co zmniejsza zacinanie się w kolejnych uruchomieniach.\n\nPozostaw WŁĄCZONE, jeśli nie masz pewności.",
|
||||
"ResolutionScaleTooltip": "Skala Rozdzielczości zastosowana do odpowiednich celów renderowania",
|
||||
"ResolutionScaleEntryTooltip": "Skala rozdzielczości zmiennoprzecinkowej, np. 1,5. Skale niecałkowite częściej powodują problemy lub awarie.",
|
||||
"AnisotropyTooltip": "Poziom filtrowania anizotropowego (ustaw na Auto, aby użyć wartości wymaganej przez grę)",
|
||||
"AspectRatioTooltip": "Współczynnik proporcji zastosowany do okna renderowania.",
|
||||
"ShaderDumpPathTooltip": "Ścieżka Zrzutu Shaderów Grafiki",
|
||||
"FileLogTooltip": "Zapisuje logowanie konsoli w pliku dziennika na dysku. Nie wpływa na wydajność.",
|
||||
"StubLogTooltip": "Wyświetla w konsoli skrótowe komunikaty dziennika. Nie wpływa na wydajność.",
|
||||
"InfoLogTooltip": "Wyświetla komunikaty dziennika informacyjnego w konsoli. Nie wpływa na wydajność.",
|
||||
"WarnLogTooltip": "Wyświetla komunikaty dziennika ostrzeżeń w konsoli. Nie wpływa na wydajność.",
|
||||
"ErrorLogTooltip": "Wyświetla w konsoli komunikaty dziennika błędów. Nie wpływa na wydajność.",
|
||||
"TraceLogTooltip": "Wyświetla komunikaty dziennika śledzenia w konsoli. Nie wpływa na wydajność.",
|
||||
"GuestLogTooltip": "Wyświetla komunikaty dziennika gości w konsoli. Nie wpływa na wydajność.",
|
||||
"FileAccessLogTooltip": "Wyświetla w konsoli komunikaty dziennika dostępu do plików.",
|
||||
"FSAccessLogModeTooltip": "Włącza wyjście dziennika dostępu FS do konsoli. Możliwe tryby to 0-3",
|
||||
"DeveloperOptionTooltip": "Używaj ostrożnie",
|
||||
"OpenGlLogLevel": "Wymaga włączonych odpowiednich poziomów logów",
|
||||
"DebugLogTooltip": "Wyświetla komunikaty dziennika debugowania w konsoli.\n\nUżywaj tego tylko na wyraźne polecenie członka załogi, ponieważ utrudni to odczytanie dzienników i pogorszy wydajność emulatora.",
|
||||
"LoadApplicationFileTooltip": "Otwórz eksplorator plików, aby wybrać plik kompatybilny z Switch do wczytania",
|
||||
"LoadApplicationFolderTooltip": "Otwórz eksplorator plików, aby wybrać zgodną z Switch, rozpakowaną aplikację do załadowania",
|
||||
"OpenRyujinxFolderTooltip": "Otwórz folder systemu plików Ryujinx",
|
||||
"OpenRyujinxLogsTooltip": "Otwiera folder, w którym zapisywane są logi",
|
||||
"ExitTooltip": "Wyjdź z Ryujinx",
|
||||
"OpenSettingsTooltip": "Otwórz okno ustawień",
|
||||
"OpenProfileManagerTooltip": "Otwórz okno Menedżera Profili Użytkownika",
|
||||
"StopEmulationTooltip": "Zatrzymaj emulację bieżącej gry i wróć do wyboru gier",
|
||||
"CheckUpdatesTooltip": "Sprawdź aktualizacje Ryujinx",
|
||||
"OpenAboutTooltip": "Otwórz Okno Informacje",
|
||||
"GridSize": "Wielkość siatki",
|
||||
"GridSizeTooltip": "Zmień rozmiar elementów siatki",
|
||||
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Brazylijski Portugalski",
|
||||
"AboutRyujinxContributorsButtonHeader": "Zobacz Wszystkich Współtwórców",
|
||||
"SettingsTabSystemAudioVolume": "Głośność: ",
|
||||
"AudioVolumeTooltip": "Zmień Głośność Dźwięku",
|
||||
"SettingsTabSystemEnableInternetAccess": "Dostęp do Internetu Gościa/Tryb LAN",
|
||||
"EnableInternetAccessTooltip": "Pozwala emulowanej aplikacji na łączenie się z Internetem.\n\nGry w trybie LAN mogą łączyć się ze sobą, gdy ta opcja jest włączona, a systemy są połączone z tym samym punktem dostępu. Dotyczy to również prawdziwych konsol.\n\nNie pozwala na łączenie się z serwerami Nintendo. Może powodować awarie niektórych gier, które próbują połączyć się z Internetem.\n\nPozostaw WYŁĄCZONE, jeśli nie masz pewności.",
|
||||
"GameListContextMenuManageCheatToolTip": "Zarządzaj Kodami",
|
||||
"GameListContextMenuManageCheat": "Zarządzaj Kodami",
|
||||
"ControllerSettingsStickRange": "Zasięg:",
|
||||
"DialogStopEmulationTitle": "Ryujinx - Zatrzymaj Emulację",
|
||||
"DialogStopEmulationMessage": "Czy na pewno chcesz zatrzymać emulację?",
|
||||
"SettingsTabCpu": "CPU",
|
||||
"SettingsTabAudio": "Dżwięk",
|
||||
"SettingsTabNetwork": "Sieć",
|
||||
"SettingsTabNetworkConnection": "Połączenie Sieciowe",
|
||||
"SettingsTabCpuCache": "Cache CPU",
|
||||
"SettingsTabCpuMemory": "Pamięć CPU",
|
||||
"DialogUpdaterFlatpakNotSupportedMessage": "Zaktualizuj Ryujinx przez FlatHub.",
|
||||
"UpdaterDisabledWarningTitle": "Aktualizator Wyłączony!",
|
||||
"GameListContextMenuOpenSdModsDirectory": "Otwórz Katalog Modów Atmosphere",
|
||||
"GameListContextMenuOpenSdModsDirectoryToolTip": "Otwiera alternatywny katalog Atmosphere na karcie SD, który zawiera modyfikacje aplikacji. Przydatne dla modów, które są pakowane dla prawdziwego sprzętu.",
|
||||
"ControllerSettingsRotate90": "Obróć o 90° w Prawo",
|
||||
"IconSize": "Rozmiar Ikon",
|
||||
"IconSizeTooltip": "Zmień rozmiar ikon gry",
|
||||
"MenuBarOptionsShowConsole": "Pokaż Konsolę",
|
||||
"ShaderCachePurgeError": "Błąd podczas czyszczenia cache shaderów w {0}: {1}",
|
||||
"UserErrorNoKeys": "Nie znaleziono kluczy",
|
||||
"UserErrorNoFirmware": "Nie znaleziono firmware'u",
|
||||
"UserErrorFirmwareParsingFailed": "Błąd parsowania firmware'u",
|
||||
"UserErrorApplicationNotFound": "Aplikacja nie znaleziona",
|
||||
"UserErrorUnknown": "Nieznany błąd",
|
||||
"UserErrorUndefined": "Niezdefiniowany błąd",
|
||||
"UserErrorNoKeysDescription": "Ryujinx nie mógł znaleźć twojego pliku 'prod.keys'",
|
||||
"UserErrorNoFirmwareDescription": "Ryujinx nie mógł znaleźć żadnego zainstalowanego firmware'u",
|
||||
"UserErrorFirmwareParsingFailedDescription": "Ryujinx nie był w stanie zparsować dostarczonego firmware'u. Jest to zwykle spowodowane nieaktualnymi kluczami.",
|
||||
"UserErrorApplicationNotFoundDescription": "Ryujinx nie mógł znaleźć prawidłowej aplikacji na podanej ścieżce.",
|
||||
"UserErrorUnknownDescription": "Wystąpił nieznany błąd!",
|
||||
"UserErrorUndefinedDescription": "Wystąpił niezdefiniowany błąd! To nie powinno się zdarzyć, skontaktuj się z deweloperem!",
|
||||
"OpenSetupGuideMessage": "Otwórz Podręcznik Konfiguracji",
|
||||
"NoUpdate": "Brak Aktualizacji",
|
||||
"TitleUpdateVersionLabel": "Wersja {0} - {1}",
|
||||
"RyujinxInfo": "Ryujinx - Info",
|
||||
"RyujinxConfirm": "Ryujinx - Potwierdzenie",
|
||||
"FileDialogAllTypes": "Wszystkie typy",
|
||||
"Never": "Nigdy",
|
||||
"SwkbdMinCharacters": "Musi mieć co najmniej {0} znaków",
|
||||
"SwkbdMinRangeCharacters": "Musi mieć długość od {0}-{1} znaków",
|
||||
"SoftwareKeyboard": "Klawiatura Oprogramowania",
|
||||
"DialogControllerAppletMessagePlayerRange": "Aplikacja żąda {0} graczy z:\n\nTYPY: {1}\n\nGRACZE: {2}\n\n{3}Otwórz Ustawienia i ponownie skonfiguruj Sterowanie lub naciśnij Zamknij.",
|
||||
"DialogControllerAppletMessage": "Aplikacja żąda dokładnie {0} graczy z:\n\nTYPY: {1}\n\nGRACZE: {2}\n\n{3}Otwórz teraz Ustawienia i ponownie skonfiguruj Sterowanie lub naciśnij Zamknij.",
|
||||
"DialogControllerAppletDockModeSet": "Ustawiono tryb Zadokowane. Przenośny też jest nieprawidłowy.\n\n",
|
||||
"UpdaterRenaming": "Zmienianie Nazw Starych Plików...",
|
||||
"UpdaterRenameFailed": "Aktualizator nie mógł zmienić nazwy pliku: {0}",
|
||||
"UpdaterAddingFiles": "Dodawanie Nowych Plików...",
|
||||
"UpdaterExtracting": "Wypakowywanie Aktualizacji...",
|
||||
"UpdaterDownloading": "Pobieranie Aktualizacji...",
|
||||
"Game": "Gra",
|
||||
"Docked": "Zadokowany",
|
||||
"Handheld": "Przenośny",
|
||||
"ConnectionError": "Błąd Połączenia.",
|
||||
"AboutPageDeveloperListMore": "{0} i więcej...",
|
||||
"ApiError": "Błąd API.",
|
||||
"LoadingHeading": "Wczytywanie {0}",
|
||||
"CompilingPPTC": "Kompilowanie PTC",
|
||||
"CompilingShaders": "Kompilowanie Shaderów",
|
||||
"AllKeyboards": "Wszystkie klawiatury",
|
||||
"OpenFileDialogTitle": "Wybierz obsługiwany plik do otwarcia",
|
||||
"OpenFolderDialogTitle": "Wybierz folder z rozpakowaną grą",
|
||||
"AllSupportedFormats": "Wszystkie Obsługiwane Formaty",
|
||||
"RyujinxUpdater": "Aktualizator Ryujinx",
|
||||
"SettingsTabHotkeys": "Skróty Klawiszowe Klawiatury",
|
||||
"SettingsTabHotkeysHotkeys": "Skróty Klawiszowe Klawiatury",
|
||||
"SettingsTabHotkeysToggleVsyncHotkey": "Przełącz VSync:",
|
||||
"SettingsTabHotkeysScreenshotHotkey": "Zrzut Ekranu:",
|
||||
"SettingsTabHotkeysShowUiHotkey": "Pokaż UI:",
|
||||
"SettingsTabHotkeysPauseHotkey": "Pauza:",
|
||||
"SettingsTabHotkeysToggleMuteHotkey": "Wycisz:",
|
||||
"ControllerMotionTitle": "Ustawienia Sterowania Ruchowego",
|
||||
"ControllerRumbleTitle": "Ustawienia Wibracji",
|
||||
"SettingsSelectThemeFileDialogTitle": "Wybierz Plik Motywu",
|
||||
"SettingsXamlThemeFile": "Plik Motywu Xaml",
|
||||
"AvatarWindowTitle": "Zarządzaj Kontami — Avatar",
|
||||
"Amiibo": "Amiibo",
|
||||
"Unknown": "Nieznane",
|
||||
"Usage": "Użycie",
|
||||
"Writable": "Zapisywalne",
|
||||
"SelectDlcDialogTitle": "Wybierz pliki DLC",
|
||||
"SelectUpdateDialogTitle": "Wybierz pliki aktualizacji",
|
||||
"UserProfileWindowTitle": "Zarządzaj Profilami Użytkowników",
|
||||
"CheatWindowTitle": "Zarządzaj Kodami do Gier",
|
||||
"DlcWindowTitle": "Zarządzaj DLC Gier",
|
||||
"UpdateWindowTitle": "Zarządzaj Aktualizacjami Gier",
|
||||
"CheatWindowHeading": "Kody Dostępne dla {0} [{1}]",
|
||||
"DlcWindowHeading": "DLC Dostępne dla {0} [{1}]",
|
||||
"UserProfilesEditProfile": "Edytuj Zaznaczone",
|
||||
"Cancel": "Anuluj",
|
||||
"Save": "Zapisz",
|
||||
"Discard": "Odrzuć",
|
||||
"UserProfilesSetProfileImage": "Ustaw Obraz Profilu",
|
||||
"UserProfileEmptyNameError": "Nazwa jest wymagana",
|
||||
"UserProfileNoImageError": "Należy ustawić obraz profilowy",
|
||||
"GameUpdateWindowHeading": "Aktualizacje Dostępne dla {0} [{1}]",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Zwiększ Rozdzielczość:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Zmniejsz Rozdzielczość:",
|
||||
"UserProfilesName": "Nazwa:",
|
||||
"UserProfilesUserId" : "ID Użytkownika:",
|
||||
"SettingsTabGraphicsBackend": "Backend Graficzny",
|
||||
"SettingsTabGraphicsBackendTooltip": "Używalne Backendy Graficzne",
|
||||
"SettingsEnableTextureRecompression": "Włącz Rekompresję Tekstur",
|
||||
"SettingsEnableTextureRecompressionTooltip": "Kompresuje niektóre tekstury w celu zmniejszenia zużycia pamięci VRAM.\n\nZalecane do użytku z GPU, które mają mniej niż 4 GB pamięci VRAM.\n\nW razie wątpliwości pozostaw WYŁĄCZONE.",
|
||||
"SettingsTabGraphicsPreferredGpu": "Preferowane GPU",
|
||||
"SettingsTabGraphicsPreferredGpuTooltip": "Wybierz kartę graficzną, która będzie używana z backendem graficznym Vulkan.\n\nNie wpływa na GPU używane przez OpenGL.\n\nW razie wątpliwości ustaw flagę GPU jako \"dGPU\". Jeśli żadnej nie ma, pozostaw nietknięte.",
|
||||
"SettingsAppRequiredRestartMessage": "Wymagane Zrestartowanie Ryujinx",
|
||||
"SettingsGpuBackendRestartMessage": "Zmieniono ustawienia Backendu Graficznego lub GPU. Będzie to wymagało ponownego uruchomienia",
|
||||
"SettingsGpuBackendRestartSubMessage": "Czy chcesz zrestartować teraz?"
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"MenuBarFileOpenApplet": "Applet'i aç",
|
||||
"MenuBarFileOpenApplet": "Applet'i Aç",
|
||||
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Mii Editör Applet'ini Bağımsız Mod'da Aç",
|
||||
"SettingsTabInputDirectMouseAccess": "Doğrudan Mouse Erişimi",
|
||||
"SettingsTabSystemMemoryManagerMode": "Hafıza Yönetim Modu:",
|
||||
@ -13,20 +13,20 @@
|
||||
"MenuBarFileOpenLogsFolder": "Logs Klasörünü aç",
|
||||
"MenuBarFileExit": "_Çıkış",
|
||||
"MenuBarOptions": "Seçenekler",
|
||||
"MenuBarOptionsToggleFullscreen": "Tam ekran modu",
|
||||
"MenuBarOptionsStartGamesInFullscreen": "Oyunları Tam Ekran Modunda başlat",
|
||||
"MenuBarOptionsStopEmulation": "Emülasyonu durdur",
|
||||
"MenuBarOptionsToggleFullscreen": "Tam Ekran Modu",
|
||||
"MenuBarOptionsStartGamesInFullscreen": "Oyunları Tam Ekran Modunda Başlat",
|
||||
"MenuBarOptionsStopEmulation": "Emülasyonu Durdur",
|
||||
"MenuBarOptionsSettings": "_Seçenekler",
|
||||
"MenuBarOptionsManageUserProfiles": "_Kullanıcı profillerini yönet",
|
||||
"MenuBarOptionsManageUserProfiles": "_Kullanıcı Profillerini Yönet",
|
||||
"MenuBarActions": "_Eylemler",
|
||||
"MenuBarOptionsSimulateWakeUpMessage": "Uyandırma mesajı simüle et",
|
||||
"MenuBarActionsScanAmiibo": "Amiibo tarama",
|
||||
"MenuBarOptionsSimulateWakeUpMessage": "Uyandırma Mesajı Simüle Et",
|
||||
"MenuBarActionsScanAmiibo": "Amiibo Tarama",
|
||||
"MenuBarTools": "_Aletler",
|
||||
"MenuBarToolsInstallFirmware": "Firmware yükle",
|
||||
"MenuBarFileToolsInstallFirmwareFromFile": "Firmware yükle (XCI veya ZIP)",
|
||||
"MenuBarFileToolsInstallFirmwareFromDirectory": "Firmware yükle (Dizin üzerinden)",
|
||||
"MenuBarToolsInstallFirmware": "Firmware Yükle",
|
||||
"MenuBarFileToolsInstallFirmwareFromFile": "Firmware Yükle (XCI veya ZIP)",
|
||||
"MenuBarFileToolsInstallFirmwareFromDirectory": "Firmware Yükle (Dizin üzerinden)",
|
||||
"MenuBarHelp": "Yardım",
|
||||
"MenuBarHelpCheckForUpdates": "Güncellemeleri denetle",
|
||||
"MenuBarHelpCheckForUpdates": "Güncellemeleri Denetle",
|
||||
"MenuBarHelpAbout": "Hakkında",
|
||||
"MenuSearch": "Arama...",
|
||||
"GameListHeaderFavorite": "Favori",
|
||||
@ -34,25 +34,25 @@
|
||||
"GameListHeaderApplication": "Oyun Adı",
|
||||
"GameListHeaderDeveloper": "Geliştirici",
|
||||
"GameListHeaderVersion": "Sürüm",
|
||||
"GameListHeaderTimePlayed": "Oynama süresi",
|
||||
"GameListHeaderLastPlayed": "Son oynama tarihi",
|
||||
"GameListHeaderTimePlayed": "Oynama Süresi",
|
||||
"GameListHeaderLastPlayed": "Son Oynama Tarihi",
|
||||
"GameListHeaderFileExtension": "Dosya Uzantısı",
|
||||
"GameListHeaderFileSize": "Dosya boyutu",
|
||||
"GameListHeaderFileSize": "Dosya Boyutu",
|
||||
"GameListHeaderPath": "Yol",
|
||||
"GameListContextMenuOpenUserSaveDirectory": "Kullanıcı Kayıt Dosyası Dizinini Aç",
|
||||
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Uygulamanın Kullanıcı Kaydının bulunduğu dizini açar",
|
||||
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Uygulamanın Kullanıcı Kaydı'nın bulunduğu dizini açar",
|
||||
"GameListContextMenuOpenUserDeviceDirectory": "Kullanıcı Cihaz Dizinini Aç",
|
||||
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Uygulamanın Kullanıcı Cihaz bulunduğu dizini açar",
|
||||
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Uygulamanın Kullanıcı Cihaz Kaydı'nın bulunduğu dizini açar",
|
||||
"GameListContextMenuOpenUserBcatDirectory": "Kullanıcı BCAT Dizinini Aç",
|
||||
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Uygulamanın Kullanıcı BCAT Kaydının bulunduğu dizini açar",
|
||||
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Uygulamanın Kullanıcı BCAT Kaydı'nın bulunduğu dizini açar",
|
||||
"GameListContextMenuManageTitleUpdates": "Oyun Güncellemelerini Yönet",
|
||||
"GameListContextMenuManageTitleUpdatesToolTip": "Oyun Güncelleme yönetim penceresini açar",
|
||||
"GameListContextMenuManageTitleUpdatesToolTip": "Oyun güncelleme yönetim penceresini açar",
|
||||
"GameListContextMenuManageDlc": "DLC Yönet",
|
||||
"GameListContextMenuManageDlcToolTip": "DLC yönetim penceresini açar",
|
||||
"GameListContextMenuOpenModsDirectory": "Mod Dizinini Aç",
|
||||
"GameListContextMenuOpenModsDirectoryToolTip": "Uygulamanın Modlarının bulunduğu dizini açar",
|
||||
"GameListContextMenuOpenModsDirectoryToolTip": "Uygulamanın modlarının bulunduğu dizini açar",
|
||||
"GameListContextMenuCacheManagement": "Cache Yönetimi",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "PPTC Cache'ini temizle",
|
||||
"GameListContextMenuCacheManagementPurgePptc": "PPTC Cache'ini Temizle",
|
||||
"GameListContextMenuCacheManagementPurgePptcToolTip": "Uygulamanın PPTC cache'ini siler",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCache": "Shader Cache'i temizle",
|
||||
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Uygulamanın shader cache'ini siler",
|
||||
@ -72,7 +72,7 @@
|
||||
"Settings": "Yapılandırma",
|
||||
"SettingsTabGeneral": "Kullancı Arayüzü",
|
||||
"SettingsTabGeneralGeneral": "Genel",
|
||||
"SettingsTabGeneralEnableDiscordRichPresence": "Discord Rich Presence'i Aç",
|
||||
"SettingsTabGeneralEnableDiscordRichPresence": "Discord Rich Presence'i Etkinleştir",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Her Açılışta Güncellemeleri Denetle",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "\"Çıkışı Onayla\" Diyaloğunu Göster",
|
||||
"SettingsTabGeneralHideCursorOnIdle": "Hareketsizlik durumunda imleci gizle",
|
||||
@ -108,7 +108,7 @@
|
||||
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Basitleştirilmiş Çince",
|
||||
"SettingsTabSystemSystemLanguageTraditionalChinese": "Geleneksel Çince",
|
||||
"SettingsTabSystemSystemTimeZone": "Sistem Saat Dilimi:",
|
||||
"SettingsTabSystemSystemTime": "System Time:",
|
||||
"SettingsTabSystemSystemTime": "Sistem Saati:",
|
||||
"SettingsTabSystemEnableVsync": "VSync'i Etkinleştir",
|
||||
"SettingsTabSystemEnablePptc": "PPTC'yi Etkinleştir (Profiled Persistent Translation Cache)",
|
||||
"SettingsTabSystemEnableFsIntegrityChecks": "FS Bütünlük Kontrollerini Etkinleştir",
|
||||
@ -124,13 +124,13 @@
|
||||
"SettingsTabGraphics": "Grafikler",
|
||||
"SettingsTabGraphicsAPI": "Grafikler API",
|
||||
"SettingsTabGraphicsEnableShaderCache": "Shader Cache'i Etkinleştir",
|
||||
"SettingsTabGraphicsAnisotropicFiltering": "Anisotropic Filtering:",
|
||||
"SettingsTabGraphicsAnisotropicFiltering": "Eşyönsüz Doku Süzmesi:",
|
||||
"SettingsTabGraphicsAnisotropicFilteringAuto": "Otomatik",
|
||||
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
|
||||
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
|
||||
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
|
||||
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
|
||||
"SettingsTabGraphicsResolutionScale": "Resolution Scale:",
|
||||
"SettingsTabGraphicsResolutionScale": "Çözünürlük Ölçeği:",
|
||||
"SettingsTabGraphicsResolutionScaleCustom": "Özel (Tavsiye Edilmez)",
|
||||
"SettingsTabGraphicsResolutionScaleNative": "Yerel (720p/1080p)",
|
||||
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
|
||||
@ -142,7 +142,7 @@
|
||||
"SettingsTabGraphicsAspectRatio16x10": "16:10",
|
||||
"SettingsTabGraphicsAspectRatio21x9": "21:9",
|
||||
"SettingsTabGraphicsAspectRatio32x9": "32:9",
|
||||
"SettingsTabGraphicsAspectRatioStretch": "Pencereye Sığdırmak için Genişlet",
|
||||
"SettingsTabGraphicsAspectRatioStretch": "Pencereye sığdırmak için genişlet",
|
||||
"SettingsTabGraphicsDeveloperOptions": "Geliştirici Seçenekleri",
|
||||
"SettingsTabGraphicsShaderDumpPath": "Grafik Shader Döküm Yolu:",
|
||||
"SettingsTabLogging": "Loglama",
|
||||
@ -164,7 +164,7 @@
|
||||
"SettingsTabLoggingOpenglLogLevelAll": "Her Şey",
|
||||
"SettingsTabLoggingEnableDebugLogs": "Hata Ayıklama Loglarını Etkinleştir",
|
||||
"SettingsTabInput": "Giriş Yöntemi",
|
||||
"SettingsTabInputEnableDockedMode": "Docked Mode'u Etkinleştir",
|
||||
"SettingsTabInputEnableDockedMode": "Docked Modunu Etkinleştir",
|
||||
"SettingsTabInputDirectKeyboardAccess": "Doğrudan Klavye Erişimi",
|
||||
"SettingsButtonSave": "Kaydet",
|
||||
"SettingsButtonClose": "Kapat",
|
||||
@ -183,7 +183,7 @@
|
||||
"ControllerSettingsRefresh": "Yenile",
|
||||
"ControllerSettingsDeviceDisabled": "Devre Dışı",
|
||||
"ControllerSettingsControllerType": "Kontrolcü Tarzı",
|
||||
"ControllerSettingsControllerTypeHandheld": "Portatif Mod",
|
||||
"ControllerSettingsControllerTypeHandheld": "Handheld",
|
||||
"ControllerSettingsControllerTypeProController": "Pro Controller",
|
||||
"ControllerSettingsControllerTypeJoyConPair": "JoyCon İkilisi",
|
||||
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon Sol",
|
||||
@ -240,14 +240,14 @@
|
||||
"ControllerSettingsRightSR": "SR",
|
||||
"ControllerSettingsExtraButtonsLeft": "Sol Tuşlar",
|
||||
"ControllerSettingsExtraButtonsRight": "Sağ Tuşlar",
|
||||
"ControllerSettingsMisc": "Misc.",
|
||||
"ControllerSettingsMisc": "Diğer",
|
||||
"ControllerSettingsTriggerThreshold": "Tetik Eşiği:",
|
||||
"ControllerSettingsMotion": "Hareket",
|
||||
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "CemuHook Uyumlu Hareket",
|
||||
"ControllerSettingsMotionControllerSlot": "Kontrolcü Yuvası:",
|
||||
"ControllerSettingsMotionMirrorInput": "Girişi Aynala",
|
||||
"ControllerSettingsMotionRightJoyConSlot": "Sağ JoyCon Yuvası:",
|
||||
"ControllerSettingsMotionServerHost": "Server Host:",
|
||||
"ControllerSettingsMotionServerHost": "Sunucu Host'u:",
|
||||
"ControllerSettingsMotionGyroSensitivity": "Gyro Hassasiyeti:",
|
||||
"ControllerSettingsMotionGyroDeadzone": "Gyro Ölü Bölgesi:",
|
||||
"ControllerSettingsSave": "Kaydet",
|
||||
@ -271,16 +271,16 @@
|
||||
"InputDialogAddNewProfileHeader": "Profil İsmi girin",
|
||||
"InputDialogAddNewProfileSubtext": "(Maksimum Uzunluk: {0})",
|
||||
"AvatarChoose": "Seç",
|
||||
"AvatarSetBackgroundColor": "Arkaplan Rengi Ayarla",
|
||||
"AvatarSetBackgroundColor": "Arka Plan Rengi Ayarla",
|
||||
"AvatarClose": "Kapat",
|
||||
"ControllerSettingsLoadProfileToolTip": "Profil Yükle",
|
||||
"ControllerSettingsAddProfileToolTip": "Profil Ekle",
|
||||
"ControllerSettingsRemoveProfileToolTip": "Profil Kaldır",
|
||||
"ControllerSettingsSaveProfileToolTip": "Profil Kaydet",
|
||||
"MenuBarFileToolsTakeScreenshot": "Ekran Görüntüsü Al",
|
||||
"MenuBarFileToolsHideUi": "Kullanıcı Arayüzünü gizle",
|
||||
"MenuBarFileToolsHideUi": "Arayüzü Gizle",
|
||||
"GameListContextMenuToggleFavorite": "Favori Ayarla",
|
||||
"GameListContextMenuToggleFavoriteToolTip": "Oyunun Favori Durumunu Aç/Kapat",
|
||||
"GameListContextMenuToggleFavoriteToolTip": "Oyunun favorilere eklenmesini veya kaldırmasını sağlar",
|
||||
"SettingsTabGeneralTheme": "Tema",
|
||||
"SettingsTabGeneralThemeCustomTheme": "Özel Tema Yolu",
|
||||
"SettingsTabGeneralThemeBaseStyle": "Temel Stil",
|
||||
@ -290,9 +290,9 @@
|
||||
"ButtonBrowse": "Göz At",
|
||||
"ControllerSettingsConfigureGeneral": "Ayarla",
|
||||
"ControllerSettingsRumble": "Titreşim",
|
||||
"ControllerSettingsRumbleStrongMultiplier": "Güçlü Titreşim Çarpanı",
|
||||
"ControllerSettingsRumbleWeakMultiplier": "Zayıf Titreşim Çarpanı",
|
||||
"DialogMessageSaveNotAvailableMessage": "{0} [{1:x16}] için kayıt verisi yok",
|
||||
"ControllerSettingsRumbleStrongMultiplier": "Güçlü Titreşim Seviyesi",
|
||||
"ControllerSettingsRumbleWeakMultiplier": "Zayıf Titreşim Seviyesi",
|
||||
"DialogMessageSaveNotAvailableMessage": "{0} [{1:x16}] için kayıt verisi bulunamadı",
|
||||
"DialogMessageSaveNotAvailableCreateSaveMessage": "Bu oyun için kayıt verisi oluşturmak ister misiniz?",
|
||||
"DialogConfirmationTitle": "Ryujinx - Onay",
|
||||
"DialogUpdaterTitle": "Ryujinx - Güncelleyici",
|
||||
@ -310,11 +310,11 @@
|
||||
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Ayıklama hatası. Ana NCA seçilen dosyada bulunamadı.",
|
||||
"DialogNcaExtractionCheckLogErrorMessage": "Ayıklama hatası. Ek bilgi için log dosyasını okuyun.",
|
||||
"DialogNcaExtractionSuccessMessage": "Ayıklama başarıyla tamamlandı.",
|
||||
"DialogUpdaterConvertFailedMessage": "Güncel Ryujinx sürümü çevrilemedi.",
|
||||
"DialogUpdaterConvertFailedMessage": "Güncel Ryujinx sürümü dönüştürülemedi.",
|
||||
"DialogUpdaterCancelUpdateMessage": "Güncelleme iptal ediliyor!",
|
||||
"DialogUpdaterAlreadyOnLatestVersionMessage": "Zaten Ryujinx'in en güncel sürümünü kullanıyorsunuz!",
|
||||
"DialogUpdaterFailedToGetVersionMessage": "Github Release'den yayınlama bilgisi alınırken hata oluştu. Bu durum yeni bir sürümün Github Actions tarafından derleniyor olmasından kaynaklanıyor olabilir. Birkaç dakika sonra tekrar deneyin.",
|
||||
"DialogUpdaterConvertFailedGithubMessage": "Github Release'den alınan Ryujinx sürümü çevrilemedi.",
|
||||
"DialogUpdaterFailedToGetVersionMessage": "Github Release'den yayınlanma bilgisi alınırken hata oluştu. Bu durum yeni bir sürümün Github Actions tarafından derleniyor olmasından kaynaklanıyor olabilir. Birkaç dakika sonra tekrar deneyin.",
|
||||
"DialogUpdaterConvertFailedGithubMessage": "Github Release'den alınan Ryujinx sürümü dönüştürülemedi.",
|
||||
"DialogUpdaterDownloadingMessage": "Güncelleme indiriliyor...",
|
||||
"DialogUpdaterExtractionMessage": "Güncelleme ayıklanıyor...",
|
||||
"DialogUpdaterRenamingMessage": "Güncelleme yeniden adlandırılıyor...",
|
||||
@ -326,19 +326,19 @@
|
||||
"DialogUpdaterNoInternetMessage": "İnternete bağlı değilsiniz!",
|
||||
"DialogUpdaterNoInternetSubMessage": "Lütfen aktif bir internet bağlantınız olduğunu kontrol edin!",
|
||||
"DialogUpdaterDirtyBuildMessage": "Ryujinx'in Dirty build'lerini güncelleyemezsiniz!",
|
||||
"DialogUpdaterDirtyBuildSubMessage": "Desteklenen bir sürüm arıyorsanız lütfen Ryujinx'i https://ryujinx.org/ sitesinden indirin.",
|
||||
"DialogUpdaterDirtyBuildSubMessage": "Desteklenen bir sürüm için lütfen Ryujinx'i https://ryujinx.org/ sitesinden indirin.",
|
||||
"DialogRestartRequiredMessage": "Yeniden Başlatma Gerekli",
|
||||
"DialogThemeRestartMessage": "Tema kaydedildi. Temayı uygulamak için yeniden başlatma gerekiyor.",
|
||||
"DialogThemeRestartSubMessage": "Yeniden başlatmak ister misiniz",
|
||||
"DialogFirmwareInstallEmbeddedMessage": "Bu oyunun içine gömülü olan firmware'i yüklemek ister misiniz? (Firmware {0})",
|
||||
"DialogFirmwareInstallEmbeddedSuccessMessage": "Yüklü firmware bulunamadı ancak Ryujinx sağlanan oyundan firmware {0} 'ı yükledi.\nRyujinx şimdi başlatılacak.",
|
||||
"DialogFirmwareInstallEmbeddedSuccessMessage": "Yüklü firmware bulunamadı ancak Ryujinx sağlanan oyundan {0} firmware sürümünü yükledi.\nRyujinx şimdi başlatılacak.",
|
||||
"DialogFirmwareNoFirmwareInstalledMessage": "Firmware Yüklü Değil",
|
||||
"DialogFirmwareInstalledMessage": "Firmware {0} yüklendi",
|
||||
"DialogOpenSettingsWindowLabel": "Seçenekler Penceresini Aç",
|
||||
"DialogControllerAppletTitle": "Controller Applet",
|
||||
"DialogMessageDialogErrorExceptionMessage": "Mesaj Diyaloğu gösterilirken hata: {0}",
|
||||
"DialogSoftwareKeyboardErrorExceptionMessage": "Mesaj Diyaloğu gösterilirken hata: {0}",
|
||||
"DialogErrorAppletErrorExceptionMessage": "Applet Diyaloğu gösterilirken hata: {0}",
|
||||
"DialogControllerAppletTitle": "Kontrolcü Applet'i",
|
||||
"DialogMessageDialogErrorExceptionMessage": "Mesaj diyaloğu gösterilirken hata: {0}",
|
||||
"DialogSoftwareKeyboardErrorExceptionMessage": "Mesaj diyaloğu gösterilirken hata: {0}",
|
||||
"DialogErrorAppletErrorExceptionMessage": "Applet diyaloğu gösterilirken hata: {0}",
|
||||
"DialogUserErrorDialogMessage": "{0}: {1}",
|
||||
"DialogUserErrorDialogInfoMessage": "\nBu hatayı düzeltmek adına daha fazla bilgi için kurulum kılavuzumuzu takip edin.",
|
||||
"DialogUserErrorDialogTitle": "Ryujinx Hatası ({0})",
|
||||
@ -355,7 +355,7 @@
|
||||
"DialogShaderDeletionMessage": "Belirtilen Shader cache silinecek :\n\n{0}\n\nDevam etmek istediğinizden emin misiniz?",
|
||||
"DialogShaderDeletionErrorMessage": "Belirtilen Shader cache temizlenirken hata {0}: {1}",
|
||||
"DialogRyujinxErrorMessage": "Ryujinx bir hata ile karşılaştı",
|
||||
"DialogInvalidTitleIdErrorMessage": "UI hatası: Seçilen oyun geçerli bir title ID'ye sahip değil",
|
||||
"DialogInvalidTitleIdErrorMessage": "Arayüz hatası: Seçilen oyun geçerli bir title ID'ye sahip değil",
|
||||
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "{0} da geçerli bir sistem firmware'i bulunamadı.",
|
||||
"DialogFirmwareInstallerFirmwareInstallTitle": "Firmware {0} Yükle",
|
||||
"DialogFirmwareInstallerFirmwareInstallMessage": "Sistem sürümü {0} yüklenecek.",
|
||||
@ -385,7 +385,7 @@
|
||||
"CommonOn": "Açık",
|
||||
"InputDialogYes": "Evet",
|
||||
"InputDialogNo": "Hayır",
|
||||
"DialogProfileInvalidProfileNameErrorMessage": "Dosya adı geçerli olmayan karakterler içeriyor. Lütfen tekrar deneyin.",
|
||||
"DialogProfileInvalidProfileNameErrorMessage": "Dosya adı geçersiz karakter içeriyor. Lütfen tekrar deneyin.",
|
||||
"MenuBarOptionsPauseEmulation": "Durdur",
|
||||
"MenuBarOptionsResumeEmulation": "Devam Et",
|
||||
"AboutUrlTooltipMessage": "Ryujinx'in websitesini varsayılan tarayıcınızda açmak için tıklayın.",
|
||||
@ -398,13 +398,13 @@
|
||||
"AboutRyujinxAboutTitle": "Hakkında:",
|
||||
"AboutRyujinxAboutContent": "Ryujinx bir Nintendo Switch™ emülatörüdür.\nLütfen bizi Patreon'da destekleyin.\nEn son haberleri Twitter veya Discord'umuzdan alın.\nKatkıda bulunmak isteyen geliştiriciler GitHub veya Discord üzerinden daha fazla bilgi edinebilir.",
|
||||
"AboutRyujinxMaintainersTitle": "Geliştiriciler:",
|
||||
"AboutRyujinxMaintainersContentTooltipMessage": "Varsayılan tarayıcınızda katkıda bulunanlar sayfasını açmak için tıklayın.",
|
||||
"AboutRyujinxMaintainersContentTooltipMessage": "Katkıda bulunanlar sayfasını varsayılan tarayıcınızda açmak için tıklayın.",
|
||||
"AboutRyujinxSupprtersTitle": "Patreon Destekleyicileri:",
|
||||
"AmiiboSeriesLabel": "Amiibo Serisi",
|
||||
"AmiiboCharacterLabel": "Karakter",
|
||||
"AmiiboScanButtonLabel": "Tarat",
|
||||
"AmiiboOptionsShowAllLabel": "Tüm Amiibo'ları Göster",
|
||||
"AmiiboOptionsUsRandomTagLabel": "Hack: Use Random tag Uuid",
|
||||
"AmiiboOptionsUsRandomTagLabel": "Hack: Rastgele bir Uuid kullan",
|
||||
"DlcManagerTableHeadingEnabledLabel": "Etkin",
|
||||
"DlcManagerTableHeadingTitleIdLabel": "Title ID",
|
||||
"DlcManagerTableHeadingContainerPathLabel": "Container Yol",
|
||||
@ -418,143 +418,164 @@
|
||||
"OrderDescending": "Azalan",
|
||||
"SettingsTabGraphicsFeatures": "Özellikler & İyileştirmeler",
|
||||
"ErrorWindowTitle": "Hata Penceresi",
|
||||
"ToggleDiscordTooltip": "Discord Rich Presence'i Aç/Kapat",
|
||||
"AddGameDirBoxTooltip": "Listeye eklemek için bir oyun dizini ekleyin",
|
||||
"ToggleDiscordTooltip": "Ryujinx'i \"şimdi oynanıyor\" Discord aktivitesinde göstermeyi veya göstermemeyi seçin",
|
||||
"AddGameDirBoxTooltip": "Listeye eklemek için oyun dizini seçin",
|
||||
"AddGameDirTooltip": "Listeye oyun dizini ekle",
|
||||
"RemoveGameDirTooltip": "Seçilen oyun dizinini kaldır",
|
||||
"CustomThemeCheckTooltip": "Grafik kullanıcı arayüzünde özel temaları etkinleştir veya devre dışı bırak",
|
||||
"CustomThemePathTooltip": "Özel grafik kullancı arayüzü teması yolu",
|
||||
"CustomThemeBrowseTooltip": "Özel grafik kullanıcı arayüzü teması için göz at",
|
||||
"DockModeToggleTooltip": "Docked Modu etkinleştir veya devre dışı bırak",
|
||||
"DirectKeyboardTooltip": "Enable or disable \"direct keyboard access (HID) support\" (Provides games access to your keyboard as a text entry device)",
|
||||
"DirectMouseTooltip": "Enable or disable \"direct mouse access (HID) support\" (Provides games access to your mouse as a pointing device)",
|
||||
"RemoveGameDirTooltip": "Seçili oyun dizinini kaldır",
|
||||
"CustomThemeCheckTooltip": "Emülatör pencerelerinin görünümünü değiştirmek için özel bir Avalonia teması kullan",
|
||||
"CustomThemePathTooltip": "Özel arayüz temasının yolu",
|
||||
"CustomThemeBrowseTooltip": "Özel arayüz teması için göz at",
|
||||
"DockModeToggleTooltip": "Docked modu emüle edilen sistemin yerleşik Nintendo Switch gibi davranmasını sağlar. Bu çoğu oyunda grafik kalitesini arttırır. Diğer yandan, bu seçeneği devre dışı bırakmak emüle edilen sistemin elde Ninendo Switch gibi davranmasını sağlayıp grafik kalitesini düşürür.\n\nDocked modu kullanmayı düşünüyorsanız 1. Oyuncu kontrollerini; Handheld modunu kullanmak istiyorsanız Handheld kontrollerini konfigüre edin.\n\nEmin değilseniz aktif halde bırakın.",
|
||||
"DirectKeyboardTooltip": "Doğrudan Klavye Erişimi (HID) desteği. Oyunların klavyenizi metin giriş cihazı olarak kullanmasını sağlar.",
|
||||
"DirectMouseTooltip": "Doğrudan Fare Erişimi (HID) desteği. Oyunların farenizi işaret aygıtı olarak kullanmasını sağlar.",
|
||||
"RegionTooltip": "Sistem Bölgesini Değiştir",
|
||||
"LanguageTooltip": "Sistem Dilini Değiştir",
|
||||
"TimezoneTooltip": "Sistem Saat Dilimini Değiştir",
|
||||
"TimeTooltip": "Sistem Saatini Değiştir",
|
||||
"VSyncToggleTooltip": "Dikey senkronizasyonu etkinleştirir veya devre dışı bırakır",
|
||||
"PptcToggleTooltip": "PPTC'yi etkinleştirir veya devre dışı bırakır",
|
||||
"FsIntegrityToggleTooltip": "Oyun içerik dosyaları için bütünlük kontrollerini etkinleştirir",
|
||||
"AudioBackendTooltip": "Ses motorunu değiştirir",
|
||||
"MemoryManagerTooltip": "Change how guest memory is mapped and accessed. Greatly affects emulated CPU performance.",
|
||||
"MemoryManagerSoftwareTooltip": "Use a software page table for address translation. Highest accuracy but slowest performance.",
|
||||
"MemoryManagerHostTooltip": "Directly map memory in the host address space. Much faster JIT compilation and execution.",
|
||||
"MemoryManagerUnsafeTooltip": "Directly map memory, but do not mask the address within the guest address space before access. Faster, but at the cost of safety. The guest application can access memory from anywhere in Ryujinx, so only run programs you trust with this mode.",
|
||||
"DRamTooltip": "Emüle edilen sistemin hafızasını 4GB'dan 6GB'a yükseltir",
|
||||
"IgnoreMissingServicesTooltip": "Eksik servisleri görmezden gelme seçeneğini etkinleştir veya devre dışı bırak",
|
||||
"GraphicsBackendThreadingTooltip": "Graphics Backend Multithreading'i etkinleştir",
|
||||
"GalThreadingTooltip": "Executes graphics backend commands on a second thread. Allows runtime multithreading of shader compilation, reduces stuttering, and improves performance on drivers without multithreading support of their own. Slightly varying peak performance on drivers with multithreading. Ryujinx may need to be restarted to correctly disable driver built-in multithreading, or you may need to do it manually to get the best performance.",
|
||||
"ShaderCacheToggleTooltip": "Shader Cache'i etkinleştir veya devre dışı bırak",
|
||||
"ResolutionScaleTooltip": "Resolution Scale applied to applicable render targets",
|
||||
"ResolutionScaleEntryTooltip": "Floating point resolution scale, such as 1.5. Non-integral scales are more likely to cause issues or crash.",
|
||||
"AnisotropyTooltip": "Anisotropic Filtering Seviyesi (Oyun tarafından istenen değeri kullanmak için Otomatik seçeneğini kullanın)",
|
||||
"AspectRatioTooltip": "Aspect Ratio applied to the renderer window.",
|
||||
"ShaderDumpPathTooltip": "Graphics Shaders Dump Path",
|
||||
"FileLogTooltip": "Diskte bir dosyaya loglamayı etkinleştirir veya devre dışı bırakır",
|
||||
"StubLogTooltip": "Stub log mesajlarını yazdırmayı etkinleştirir",
|
||||
"InfoLogTooltip": "Bilgi log mesajlarını yazdırmayı etkinleştirir",
|
||||
"WarnLogTooltip": "Uyarı log mesajlarını yazdırmayı etkinleştirir",
|
||||
"ErrorLogTooltip": "Hata log mesajlarını yazdırmayı etkinleştirir",
|
||||
"TraceLogTooltip": "Trace log mesajlarını yazdırmayı etkinleştirir",
|
||||
"GuestLogTooltip": "Guest log mesajlarını yazdırmayı etkinleştirir",
|
||||
"FileAccessLogTooltip": "Dosya erişim log mesajlarını yazdırmayı etkinleştirir",
|
||||
"FSAccessLogModeTooltip": "Enables FS access log output to the console. Possible modes are 0-3",
|
||||
"VSyncToggleTooltip": "Emüle edilen konsolun Dikey Senkronizasyonu. Çoğu oyun için kare sınırlayıcı işlevi görür, bu seçeneği devre dışı bırakmak bazı oyunların normalden yüksek hızda çalışmasını ve yükleme ekranlarının daha uzun sürmesini veya sıkışıp kalmasını sağlar.\n\nTercih ettiğiniz bir kısayol ile oyun içindeyken etkinleştirilip devre dışı bırakılabilir. Bu seçeneği devre dışı bırakmayı düşünüyorsanız bir kısayol atamanızı öneririz.\n\nEmin değilseniz aktif halde bırakın.",
|
||||
"PptcToggleTooltip": "Çevrilen JIT fonksiyonlarını oyun her açıldığında çevrilmek zorunda kalmaması için kaydeder.\n\nTeklemeyi azaltır ve ilk açılıştan sonra oyunların ilk açılış süresini ciddi biçimde hızlandırır.\n\nEmin değilseniz aktif halde bırakın.",
|
||||
"FsIntegrityToggleTooltip": "Oyun açarken hatalı dosyaların olup olmadığını kontrol eder, ve hatalı dosya bulursa log dosyasında hash hatası görüntüler.\n\nPerformansa herhangi bir etkisi yoktur ve sorun gidermeye yardımcı olur.\n\nEmin değilseniz aktif halde bırakın.",
|
||||
"AudioBackendTooltip": "Ses çıkış motorunu değiştirir.\n\nSDL2 tercih edilen seçenektir, OpenAL ve SoundIO ise alternatif olarak kullanılabilir. Dummy seçeneğinde ses çıkışı olmayacaktır.\n\nEmin değilseniz SDL2 seçeneğine ayarlayın.",
|
||||
"MemoryManagerTooltip": "Guest hafızasının nasıl tahsis edilip erişildiğini değiştirir. Emüle edilen CPU performansını ciddi biçimde etkiler.\n\nEmin değilseniz HOST UNCHECKED seçeneğine ayarlayın.",
|
||||
"MemoryManagerSoftwareTooltip": "Adres çevirisi için bir işlemci sayfası kullanır. En yüksek doğruluğu ve en yavaş performansı sunar.",
|
||||
"MemoryManagerHostTooltip": "Hafızayı doğrudan host adres aralığında tahsis eder. Çok daha hızlı JIT derleme ve işletimi sunar.",
|
||||
"MemoryManagerUnsafeTooltip": "Hafızayı doğrudan tahsis eder, ancak host aralığına erişimden önce adresi maskelemez. Daha iyi performansa karşılık emniyetten ödün verir. Misafir uygulama Ryujinx içerisinden istediği hafızaya erişebilir, bu sebeple bu seçenek ile sadece güvendiğiniz uygulamaları çalıştırın.",
|
||||
"DRamTooltip": "Emüle edilen sistem hafızasını 4GB'dan 6GB'a yükseltir.\n\nBu seçenek yalnızca yüksek çözünürlük doku paketleri veya 4k çözünürlük modları için kullanılır. Performansı artırMAZ!\n\nEmin değilseniz devre dışı bırakın.",
|
||||
"IgnoreMissingServicesTooltip": "Henüz programlanmamış Horizon işletim sistemi servislerini görmezden gelir. Bu seçenek belirli oyunların açılırken çökmesinin önüne geçmeye yardımcı olabilir.\n\nEmin değilseniz devre dışı bırakın.",
|
||||
"GraphicsBackendThreadingTooltip": "Grafik arka uç komutlarını ikinci bir iş parçacığında işletir.\n\nKendi multithreading desteği olmayan sürücülerde shader derlemeyi hızlandırıp performansı artırır. Multithreading desteği olan sürücülerde çok az daha iyi performans sağlar.\n\nEmin değilseniz Otomatik seçeneğine ayarlayın.",
|
||||
"GalThreadingTooltip": "Grafik arka uç komutlarını ikinci bir iş parçacığında işletir.\n\nKendi multithreading desteği olmayan sürücülerde shader derlemeyi hızlandırıp performansı artırır. Multithreading desteği olan sürücülerde çok az daha iyi performans sağlar.\n\nEmin değilseniz Otomatik seçeneğine ayarlayın.",
|
||||
"ShaderCacheToggleTooltip": "Saves a disk shader cache which reduces stuttering in subsequent runs.\n\nLeave ON if unsure.",
|
||||
"ResolutionScaleTooltip": "Uygulanabilir grafik hedeflerine uygulanan çözünürlük ölçeği",
|
||||
"ResolutionScaleEntryTooltip": "Küsüratlı çözünürlük ölçeği, 1.5 gibi. Küsüratlı ölçekler hata oluşturmaya ve çökmeye daha yatkındır.",
|
||||
"AnisotropyTooltip": "Eşyönsüz doku süzmesi seviyesi (Oyun tarafından istenen değeri kullanmak için Otomatik seçeneğine ayarlayın)",
|
||||
"AspectRatioTooltip": "Grafik penceresine uygulanan en-boy oranı.",
|
||||
"ShaderDumpPathTooltip": "Grafik Shader Döküm Yolu",
|
||||
"FileLogTooltip": "Konsol loglarını diskte bir log dosyasına kaydeder. Performansı etkilemez.",
|
||||
"StubLogTooltip": "Stub log mesajlarını konsola yazdırır. Performansı etkilemez.",
|
||||
"InfoLogTooltip": "Bilgi log mesajlarını konsola yazdırır. Performansı etkilemez.",
|
||||
"WarnLogTooltip": "Uyarı log mesajlarını konsola yazdırır. Performansı etkilemez.",
|
||||
"ErrorLogTooltip": "Hata log mesajlarını konsola yazdırır. Performansı etkilemez.",
|
||||
"TraceLogTooltip": "Trace log mesajlarını konsola yazdırır. Performansı etkilemez.",
|
||||
"GuestLogTooltip": "Guest log mesajlarını konsola yazdırır. Performansı etkilemez.",
|
||||
"FileAccessLogTooltip": "Dosya sistemi erişim log mesajlarını konsola yazdırır.",
|
||||
"FSAccessLogModeTooltip": "Konsola FS erişim loglarının yazılmasını etkinleştirir. Kullanılabilir modlar 0-3'tür",
|
||||
"DeveloperOptionTooltip": "Dikkatli kullanın",
|
||||
"OpenGlLogLevel": "Uygun log seviyelerinin etkin olmasını gerektirir",
|
||||
"DebugLogTooltip": "Debug log mesajlarını yazdırmayı etkinleştirir",
|
||||
"LoadApplicationFileTooltip": "Switch'e uyumlu bir dosya açmak için bir dosya seçim arayüzü açar",
|
||||
"LoadApplicationFolderTooltip": "Switch'e uyumlu sıkıştırılmamış uygulama açmak için bir dosya seçim arayüzü açar",
|
||||
"OpenRyujinxFolderTooltip": "Ryujinx dosya sistemi klasörünü açar",
|
||||
"OpenRyujinxLogsTooltip": "Log kayıtlarının yazıldığı klasörü açar",
|
||||
"ExitTooltip": "Ryujinx'i Kapat",
|
||||
"OpenSettingsTooltip": "Seçenekler penceresini aç",
|
||||
"OpenProfileManagerTooltip": "Kullanıcı Profil Yönetimi penceresini açar",
|
||||
"StopEmulationTooltip": "Güncel oyunun emülasyonunu durdurup oyun seçimine geri dönün",
|
||||
"CheckUpdatesTooltip": "Ryujinx güncellemelerini denetle",
|
||||
"OpenAboutTooltip": "Hakkında penceresini aç",
|
||||
"GridSize": "Grid Boyutu",
|
||||
"GridSizeTooltip": "Grid itemlerinin boyutunu değiştir",
|
||||
"OpenGlLogLevel": "Uygun log seviyesinin aktif olmasını gerektirir",
|
||||
"DebugLogTooltip": "Debug log mesajlarını konsola yazdırır.\n\nBu seçeneği yalnızca geliştirici üyemiz belirtirse aktifleştirin, çünkü bu seçenek log dosyasını okumayı zorlaştırır ve emülatörün performansını düşürür.",
|
||||
"LoadApplicationFileTooltip": "Switch ile uyumlu bir dosya yüklemek için dosya tarayıcısını açar",
|
||||
"LoadApplicationFolderTooltip": "Switch ile uyumlu ayrıştırılmamış bir uygulama yüklemek için dosya tarayıcısını açar",
|
||||
"OpenRyujinxFolderTooltip": "Ryujinx dosya sistem klasörünü açar",
|
||||
"OpenRyujinxLogsTooltip": "Log dosyalarının bulunduğu klasörü açar",
|
||||
"ExitTooltip": "Ryujinx'ten çıkış yapmayı sağlar",
|
||||
"OpenSettingsTooltip": "Seçenekler penceresini açar",
|
||||
"OpenProfileManagerTooltip": "Kullanıcı profil yöneticisi penceresini açar",
|
||||
"StopEmulationTooltip": "Oynanmakta olan oyunun emülasyonunu durdurup oyun seçimine geri döndürür",
|
||||
"CheckUpdatesTooltip": "Ryujinx güncellemelerini denetlemeyi sağlar",
|
||||
"OpenAboutTooltip": "Hakkında penceresini açar",
|
||||
"GridSize": "Öge Boyutu",
|
||||
"GridSizeTooltip": "Grid ögelerinin boyutunu değiştirmeyi sağlar",
|
||||
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Brezilya Portekizcesi",
|
||||
"AboutRyujinxContributorsButtonHeader": "Tüm katkıda bulunanları gör",
|
||||
"SettingsTabSystemAudioVolume": "Ses Seviyesi: ",
|
||||
"AudioVolumeTooltip": "Ses seviyesini değiştir",
|
||||
"SettingsTabSystemEnableInternetAccess": "Guest Internet Erişimini Etkinleştir",
|
||||
"EnableInternetAccessTooltip": "Guest internet erişimini etkinleştirir. Etkinleştirilmişse, uygulama emüle edilen Switch konsolu internete bağlıymış gibi davranır. Not: Bazı durumlarda uygulamalar bu seçenek devre dışı olmasına rağmen internete erişebilir",
|
||||
"GameListContextMenuManageCheatToolTip" : "Hileleri Yönet",
|
||||
"GameListContextMenuManageCheat" : "Hileleri Yönet",
|
||||
"ControllerSettingsStickRange" : "Bölge (Range):",
|
||||
"DialogStopEmulationTitle" : "Ryujinx - Emülasyonu Durdur",
|
||||
"AudioVolumeTooltip": "Ses seviyesini değiştirir",
|
||||
"SettingsTabSystemEnableInternetAccess": "Guest Internet Erişimi/LAN Modu",
|
||||
"EnableInternetAccessTooltip": "Emüle edilen uygulamanın internete bağlanmasını sağlar.\n\nLAN modu bulunan oyunlar bu seçenek ile birbirine bağlanabilir ve sistemler aynı access point'e bağlanır. Bu gerçek konsolları da kapsar.\n\nNintendo sunucularına bağlanmayı sağlaMAZ. Internete bağlanmaya çalışan baz oyunların çökmesine sebep olabilr.\n\nEmin değilseniz devre dışı bırakın.",
|
||||
"GameListContextMenuManageCheatToolTip": "Hileleri yönetmeyi sağlar",
|
||||
"GameListContextMenuManageCheat": "Hileleri Yönet",
|
||||
"ControllerSettingsStickRange": "Menzil:",
|
||||
"DialogStopEmulationTitle": "Ryujinx - Emülasyonu Durdur",
|
||||
"DialogStopEmulationMessage": "Emülasyonu durdurmak istediğinizden emin misiniz?",
|
||||
"SettingsTabCpu": "CPU",
|
||||
"SettingsTabAudio": "Ses",
|
||||
"SettingsTabNetwork": "Ağ",
|
||||
"SettingsTabNetworkConnection" : "Ağ Bağlantısı",
|
||||
"SettingsTabCpuCache" : "CPU Cache",
|
||||
"SettingsTabCpuMemory" : "CPU Hafızası",
|
||||
"SettingsTabNetworkConnection": "Ağ Bağlantısı",
|
||||
"SettingsTabCpuCache": "CPU Cache",
|
||||
"SettingsTabCpuMemory": "CPU Hafızası",
|
||||
"DialogUpdaterFlatpakNotSupportedMessage": "Lütfen Ryujinx'i FlatHub aracılığıyla güncelleyin.",
|
||||
"UpdaterDisabledWarningTitle": "Güncelleme aracı devre dışı!",
|
||||
"GameListContextMenuOpenSdModsDirectory": "Atmosphere Modları Dizinini Aç",
|
||||
"GameListContextMenuOpenSdModsDirectoryToolTip": "Uygulamanın modlarının bulunduğu alternatif atmosphere SD kart dizinini açar",
|
||||
"ControllerSettingsRotate90": "Saat yönünde 90° döndür",
|
||||
"IconSize": "Simge Boyutu",
|
||||
"IconSizeTooltip": "Oyunların simge boyutlarını değiştirir",
|
||||
"MenuBarOptionsShowConsole": "Konsolu Göster",
|
||||
"ShaderCachePurgeError" : "Belirtilen shader cache temizlenirken hata {0}: {1}",
|
||||
"UpdaterDisabledWarningTitle": "Güncelleyici Devre Dışı!",
|
||||
"GameListContextMenuOpenSdModsDirectory": "Atmosphere Mod Dizini",
|
||||
"GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods. Useful for mods that are packaged for real hardware.",
|
||||
"ControllerSettingsRotate90": "Saat yönünde 90° Döndür",
|
||||
"IconSize": "Ikon Boyutu",
|
||||
"IconSizeTooltip": "Oyun ikonlarının boyutunu değiştirmeyi sağlar",
|
||||
"MenuBarOptionsShowConsole": "Konsol'u Göster",
|
||||
"ShaderCachePurgeError": "Belirtilen shader cache temizlenirken hata {0}: {1}",
|
||||
"UserErrorNoKeys": "Keys bulunamadı",
|
||||
"UserErrorNoFirmware": "Firmware bulunamadı",
|
||||
"UserErrorFirmwareParsingFailed": "Firmware çözümleme hatası",
|
||||
"UserErrorApplicationNotFound": "Uygulama bulunamadı",
|
||||
"UserErrorUnknown": "Bilinmeyen hata",
|
||||
"UserErrorUndefined": "Tanımlanmamış hata",
|
||||
"UserErrorNoKeysDescription": "Ryujinx 'prod.keys' dosyanızı bulamadı",
|
||||
"UserErrorNoFirmwareDescription": "Ryujinx yüklü firmware bulamadı",
|
||||
"UserErrorFirmwareParsingFailedDescription": "Ryujinx verilen firmware'i çözümleyemedi. Bu durum genellikle güncel olmayan key'lerden kaynaklanır.",
|
||||
"UserErrorApplicationNotFoundDescription": "Ryujinx verilen yolda geçerli bir uygulama bulamadı.",
|
||||
"UserErrorUndefined": "Tanımlanmayan hata",
|
||||
"UserErrorNoKeysDescription": "Ryujinx 'prod.keys' dosyasını bulamadı",
|
||||
"UserErrorNoFirmwareDescription": "Ryujinx yüklü herhangi firmware bulamadı",
|
||||
"UserErrorFirmwareParsingFailedDescription": "Ryujinx temin edilen firmware'i çözümleyemedi. Bu durum genellikle güncel olmayan keys'den kaynaklanır.",
|
||||
"UserErrorApplicationNotFoundDescription": "Ryujinx belirtilen yolda geçerli bir uygulama bulamadı.",
|
||||
"UserErrorUnknownDescription": "Bilinmeyen bir hata oluştu!",
|
||||
"UserErrorUndefinedDescription": "Tanımlanmamış bir hata oluştu! Bu durumla karşılaşılmamalı, lütfen bir geliştirici ile iletişime geçin!",
|
||||
"OpenSetupGuideMessage": "Kurulum kılavuzunu aç",
|
||||
"UserErrorUndefinedDescription": "Tanımlanmayan bir hata oluştu! Bu durum ile karşılaşılmamalıydı, lütfen bir geliştirici ile iletişime geçin!",
|
||||
"OpenSetupGuideMessage": "Kurulum Kılavuzunu Aç",
|
||||
"NoUpdate": "Güncelleme Yok",
|
||||
"TitleUpdateVersionLabel": "Sürüm {0} - {1}",
|
||||
"RyujinxInfo": "Ryujinx - Bilgi",
|
||||
"RyujinxConfirm": "Ryujinx - Onay",
|
||||
"FileDialogAllTypes": "Tüm tarzlar",
|
||||
"RyujinxConfirm": "Ryujinx - Doğrulama",
|
||||
"FileDialogAllTypes": "Tüm türler",
|
||||
"Never": "Hiçbir Zaman",
|
||||
"SwkbdMinCharacters": "En az {0} karakter uzunluğunda olmalı",
|
||||
"SwkbdMinRangeCharacters": "En az {0}-{1} karakter uzunluğunda olmalı",
|
||||
"SoftwareKeyboard": "Software Klavyesi",
|
||||
"DialogControllerAppletMessagePlayerRange": "Uygulama {0} oyuncu(lar) talep eder player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
|
||||
"DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
|
||||
"DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n",
|
||||
"SwkbdMinRangeCharacters": "{0}-{1} karakter uzunluğunda olmalı",
|
||||
"SoftwareKeyboard": "Yazılım Klavyesi",
|
||||
"DialogControllerAppletMessagePlayerRange": "Uygulama belirtilen türde {0} oyuncu istiyor:\n\nTÜRLER: {1}\n\nOYUNCULAR: {2}\n\n{3}Lütfen şimdi seçeneklerden giriş aygıtlarını ayarlayın veya Kapat'a basın.",
|
||||
"DialogControllerAppletMessage": "Uygulama belirtilen türde tam olarak {0} oyuncu istiyor:\n\nTÜRLER: {1}\n\nOYUNCULAR: {2}\n\n{3}Lütfen şimdi seçeneklerden giriş aygıtlarını ayarlayın veya Kapat'a basın.",
|
||||
"DialogControllerAppletDockModeSet": "Docked mode etkin. Handheld geçersiz.\n\n",
|
||||
"UpdaterRenaming": "Eski dosyalar yeniden adlandırılıyor...",
|
||||
"UpdaterRenameFailed": "Güncelleme aracı belirilen dosyayı yeniden adlandıramadı: {0}",
|
||||
"UpdaterAddingFiles": "Yeni dosyalar ekleniyor...",
|
||||
"UpdaterExtracting": "Güncelleme ayıklanıyor...",
|
||||
"UpdaterDownloading": "Güncelleme indiriliyor...",
|
||||
"UpdaterRenameFailed": "Güncelleyici belirtilen dosyayı yeniden adlandıramadı: {0}",
|
||||
"UpdaterAddingFiles": "Yeni Dosyalar Ekleniyor...",
|
||||
"UpdaterExtracting": "Güncelleme Ayrıştırılıyor...",
|
||||
"UpdaterDownloading": "Güncelleme İndiriliyor...",
|
||||
"Game": "Oyun",
|
||||
"Docked": "Docked",
|
||||
"Handheld": "Handheld",
|
||||
"ConnectionError": "Bağlantı Hatası.",
|
||||
"AboutPageDeveloperListMore": "{0} ve daha fazla...",
|
||||
"ApiError": "API Hatası.",
|
||||
"LoadingHeading": "Yükleniyor {0}",
|
||||
"CompilingPPTC": "PTC derleniyor",
|
||||
"CompilingShaders": "Shaderlar derleniyor",
|
||||
"AllKeyboards": "Tüm klavyeler",
|
||||
"OpenFileDialogTitle": "Açılacak desteklenen bir dosya seçin",
|
||||
"OpenFolderDialogTitle": "Sıkıştırılmamış oyun içeren klasör seçin",
|
||||
"LoadingHeading": "{0} Yükleniyor",
|
||||
"CompilingPPTC": "PTC Derleniyor",
|
||||
"CompilingShaders": "Shaderlar Derleniyor",
|
||||
"AllKeyboards": "Tüm Klavyeler",
|
||||
"OpenFileDialogTitle": "Açmak için desteklenen bir dosya seçin",
|
||||
"OpenFolderDialogTitle": "Ayrıştırılmamış oyun içeren bir klasör seçin",
|
||||
"AllSupportedFormats": "Tüm Desteklenen Formatlar",
|
||||
"RyujinxUpdater": "Ryujinx Güncelleyicisi",
|
||||
"SettingsTabHotkeys": "Klavye Kısayolları",
|
||||
"SettingsTabHotkeysHotkeys": "Klavye Kısayolları",
|
||||
"SettingsTabHotkeysToggleVsyncHotkey": "VSync'i Etkinleştir:",
|
||||
"SettingsTabHotkeysToggleVsyncHotkey": "VSync'i Etkinleştir/Devre Dışı Bırak:",
|
||||
"SettingsTabHotkeysScreenshotHotkey": "Ekran Görüntüsü Al:",
|
||||
"SettingsTabHotkeysShowUiHotkey": "Arayüzü Göster:",
|
||||
"SettingsTabHotkeysPauseHotkey": "Duraklat:",
|
||||
"SettingsTabHotkeysPauseHotkey": "Durdur:",
|
||||
"SettingsTabHotkeysToggleMuteHotkey": "Sustur:",
|
||||
"ControllerMotionTitle": "Hareket Kontrol Seçenekleri",
|
||||
"ControllerRumbleTitle": "Titreşim Seçenekleri",
|
||||
"SettingsSelectThemeFileDialogTitle" : "Tema Dosyası Seçin",
|
||||
"SettingsXamlThemeFile" : "Xaml Tema Dosyası",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Çözünürlüğü artırın:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Çözünürlüğü azaltın:"
|
||||
"SettingsSelectThemeFileDialogTitle": "Tema Dosyası Seç",
|
||||
"SettingsXamlThemeFile": "Xaml Tema Dosyası",
|
||||
"AvatarWindowTitle": "Hesapları Yönet - Avatar",
|
||||
"Amiibo": "Amiibo",
|
||||
"Unknown": "Bilinmeyen",
|
||||
"Usage": "Kullanım",
|
||||
"Writable": "Yazılabilir",
|
||||
"SelectDlcDialogTitle": "DLC dosyalarını seç",
|
||||
"SelectUpdateDialogTitle": "Güncelleme dosyalarını seç",
|
||||
"UserProfileWindowTitle": "Kullanıcı Profillerini Yönet",
|
||||
"CheatWindowTitle": "Oyun Hilelerini Yönet",
|
||||
"DlcWindowTitle": "Oyun DLC'lerini Yönet",
|
||||
"UpdateWindowTitle": "Oyun Güncellemelerini Yönet",
|
||||
"CheatWindowHeading": "{0} için Hile mevcut [{1}]",
|
||||
"DlcWindowHeading": "{0} için DLC mevcut [{1}]",
|
||||
"UserProfilesEditProfile": "Seçiliyi Düzenle",
|
||||
"Cancel": "İptal",
|
||||
"Save": "Kaydet",
|
||||
"Discard": "Iskarta",
|
||||
"UserProfilesSetProfileImage": "Profil Resmi Ayarla",
|
||||
"UserProfileEmptyNameError": "İsim gerekli",
|
||||
"UserProfileNoImageError": "Profil resmi ayarlanmalıdır",
|
||||
"GameUpdateWindowHeading": "{0} için güncellemeler mevcut [{1}]",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "Çözünürlüğü artır:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "Çözünürlüğü azalt:"
|
||||
}
|
||||
|
@ -34,8 +34,8 @@
|
||||
"GameListHeaderApplication": "名称",
|
||||
"GameListHeaderDeveloper": "制作商",
|
||||
"GameListHeaderVersion": "版本",
|
||||
"GameListHeaderTimePlayed": "游玩时间",
|
||||
"GameListHeaderLastPlayed": "上次游玩",
|
||||
"GameListHeaderTimePlayed": "游玩时长",
|
||||
"GameListHeaderLastPlayed": "最近游玩",
|
||||
"GameListHeaderFileExtension": "扩展名",
|
||||
"GameListHeaderFileSize": "大小",
|
||||
"GameListHeaderPath": "路径",
|
||||
@ -109,9 +109,9 @@
|
||||
"SettingsTabSystemSystemLanguageTraditionalChinese": "繁体中文(推荐)",
|
||||
"SettingsTabSystemSystemTimeZone": "系统时区:",
|
||||
"SettingsTabSystemSystemTime": "系统时钟:",
|
||||
"SettingsTabSystemEnableVsync": "开启 VSync",
|
||||
"SettingsTabSystemEnableVsync": "启用 VSync",
|
||||
"SettingsTabSystemEnablePptc": "开启 PPTC 缓存",
|
||||
"SettingsTabSystemEnableFsIntegrityChecks": "开启文件系统完整性检查",
|
||||
"SettingsTabSystemEnableFsIntegrityChecks": "文件系统完整性检查",
|
||||
"SettingsTabSystemAudioBackend": "音频后端:",
|
||||
"SettingsTabSystemAudioBackendDummy": "无",
|
||||
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
|
||||
@ -121,8 +121,8 @@
|
||||
"SettingsTabSystemHacksNote": " (会引起模拟器不稳定)",
|
||||
"SettingsTabSystemExpandDramSize": "将模拟RAM大小扩展到 6GB",
|
||||
"SettingsTabSystemIgnoreMissingServices": "忽略缺少的服务",
|
||||
"SettingsTabGraphics": "图像",
|
||||
"SettingsTabGraphicsAPI": "的图形 API",
|
||||
"SettingsTabGraphics": "图形",
|
||||
"SettingsTabGraphicsAPI": "图形 API",
|
||||
"SettingsTabGraphicsEnableShaderCache": "启用着色器缓存",
|
||||
"SettingsTabGraphicsAnisotropicFiltering": "各向异性过滤:",
|
||||
"SettingsTabGraphicsAnisotropicFilteringAuto": "自动",
|
||||
@ -206,22 +206,22 @@
|
||||
"ControllerSettingsDPadLeft": "左",
|
||||
"ControllerSettingsDPadRight": "右",
|
||||
"ControllerSettingsLStick": "左摇杆",
|
||||
"ControllerSettingsLStickButton": "按下",
|
||||
"ControllerSettingsLStickButton": "按下摇杆",
|
||||
"ControllerSettingsLStickUp": "上",
|
||||
"ControllerSettingsLStickDown": "下",
|
||||
"ControllerSettingsLStickLeft": "左",
|
||||
"ControllerSettingsLStickRight": "右",
|
||||
"ControllerSettingsLStickStick": "杆",
|
||||
"ControllerSettingsLStickStick": "摇杆",
|
||||
"ControllerSettingsLStickInvertXAxis": "反转 X 方向",
|
||||
"ControllerSettingsLStickInvertYAxis": "反转 Y 方向",
|
||||
"ControllerSettingsLStickDeadzone": "死区:",
|
||||
"ControllerSettingsRStick": "右摇杆",
|
||||
"ControllerSettingsRStickButton": "按下",
|
||||
"ControllerSettingsRStickButton": "按下摇杆",
|
||||
"ControllerSettingsRStickUp": "上",
|
||||
"ControllerSettingsRStickDown": "下",
|
||||
"ControllerSettingsRStickLeft": "左",
|
||||
"ControllerSettingsRStickRight": "右",
|
||||
"ControllerSettingsRStickStick": "杆",
|
||||
"ControllerSettingsRStickStick": "摇杆",
|
||||
"ControllerSettingsRStickInvertXAxis": "反转 X 方向",
|
||||
"ControllerSettingsRStickInvertYAxis": "反转 Y 方向",
|
||||
"ControllerSettingsRStickDeadzone": "死区:",
|
||||
@ -238,15 +238,15 @@
|
||||
"ControllerSettingsLeftSR": "SR",
|
||||
"ControllerSettingsRightSL": "SL",
|
||||
"ControllerSettingsRightSR": "SR",
|
||||
"ControllerSettingsExtraButtonsLeft": "左按键",
|
||||
"ControllerSettingsExtraButtonsRight": "右按键",
|
||||
"ControllerSettingsExtraButtonsLeft": "左背键",
|
||||
"ControllerSettingsExtraButtonsRight": "右背键",
|
||||
"ControllerSettingsMisc": "其他",
|
||||
"ControllerSettingsTriggerThreshold": "扳机阈值:",
|
||||
"ControllerSettingsMotion": "体感",
|
||||
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "使用 CemuHook 体感协议",
|
||||
"ControllerSettingsMotionControllerSlot": "手柄:",
|
||||
"ControllerSettingsMotionMirrorInput": "镜像操作",
|
||||
"ControllerSettingsMotionRightJoyConSlot": "右 JoyCon:",
|
||||
"ControllerSettingsMotionRightJoyConSlot": "右JoyCon:",
|
||||
"ControllerSettingsMotionServerHost": "服务器 Host:",
|
||||
"ControllerSettingsMotionGyroSensitivity": "陀螺仪敏感度:",
|
||||
"ControllerSettingsMotionGyroDeadzone": "陀螺仪死区:",
|
||||
@ -255,9 +255,9 @@
|
||||
"UserProfilesSelectedUserProfile": "选择的用户账户:",
|
||||
"UserProfilesSaveProfileName": "保存名称",
|
||||
"UserProfilesChangeProfileImage": "更换头像",
|
||||
"UserProfilesAvailableUserProfiles": "现有的账户:",
|
||||
"UserProfilesAvailableUserProfiles": "现有账户:",
|
||||
"UserProfilesAddNewProfile": "新建账户",
|
||||
"UserProfilesDeleteSelectedProfile": "删除选择的账户",
|
||||
"UserProfilesDeleteSelectedProfile": "删除选中账户",
|
||||
"UserProfilesClose": "关闭",
|
||||
"ProfileImageSelectionTitle": "头像选择",
|
||||
"ProfileImageSelectionHeader": "选择合适的头像图片",
|
||||
@ -280,7 +280,7 @@
|
||||
"MenuBarFileToolsTakeScreenshot": "保存截图",
|
||||
"MenuBarFileToolsHideUi": "隐藏UI",
|
||||
"GameListContextMenuToggleFavorite": "收藏",
|
||||
"GameListContextMenuToggleFavoriteToolTip": "启用或取消收藏标记",
|
||||
"GameListContextMenuToggleFavoriteToolTip": "标记喜爱的游戏",
|
||||
"SettingsTabGeneralTheme": "主题",
|
||||
"SettingsTabGeneralThemeCustomTheme": "自选主题路径",
|
||||
"SettingsTabGeneralThemeBaseStyle": "主题色调",
|
||||
@ -290,8 +290,8 @@
|
||||
"ButtonBrowse": "浏览",
|
||||
"ControllerSettingsConfigureGeneral": "配置",
|
||||
"ControllerSettingsRumble": "震动",
|
||||
"ControllerSettingsRumbleStrongMultiplier": "强震动调节",
|
||||
"ControllerSettingsRumbleWeakMultiplier": "弱震动调节",
|
||||
"ControllerSettingsRumbleStrongMultiplier": "强震动幅度",
|
||||
"ControllerSettingsRumbleWeakMultiplier": "弱震动幅度",
|
||||
"DialogMessageSaveNotAvailableMessage": "没有{0} [{1:x16}]的游戏存档",
|
||||
"DialogMessageSaveNotAvailableCreateSaveMessage": "是否创建该游戏的存档文件夹?",
|
||||
"DialogConfirmationTitle": "Ryujinx - 设置",
|
||||
@ -299,7 +299,7 @@
|
||||
"DialogErrorTitle": "Ryujinx - 错误",
|
||||
"DialogWarningTitle": "Ryujinx - 警告",
|
||||
"DialogExitTitle": "Ryujinx - 关闭",
|
||||
"DialogErrorMessage": "Ryujinx 遇到了错误",
|
||||
"DialogErrorMessage": "Ryujinx 发生错误",
|
||||
"DialogExitMessage": "是否关闭 Ryujinx?",
|
||||
"DialogExitSubMessage": "未保存的进度会丢失",
|
||||
"DialogMessageCreateSaveErrorMessage": "创建特定的存档时出错: {0}",
|
||||
@ -313,7 +313,7 @@
|
||||
"DialogUpdaterConvertFailedMessage": "无法转换当前 Ryujinx 版本。",
|
||||
"DialogUpdaterCancelUpdateMessage": "更新取消!",
|
||||
"DialogUpdaterAlreadyOnLatestVersionMessage": "您使用的 Ryujinx 是最新版本。",
|
||||
"DialogUpdaterFailedToGetVersionMessage": "尝试从 Github 获取版本信息时无效。\\n可能由于 GitHub Actions 正在编译新版本。请过几分钟重试。",
|
||||
"DialogUpdaterFailedToGetVersionMessage": "尝试从 Github 获取版本信息时无效。\n可能由于 GitHub Actions 正在编译新版本。请过几分钟重试。",
|
||||
"DialogUpdaterConvertFailedGithubMessage": "无法转换从 Github 接收到的 Ryujinx 版本。",
|
||||
"DialogUpdaterDownloadingMessage": "下载新版本中...",
|
||||
"DialogUpdaterExtractionMessage": "正在提取更新...",
|
||||
@ -331,7 +331,7 @@
|
||||
"DialogThemeRestartMessage": "主题设置已保存。需要重新启动才能生效。",
|
||||
"DialogThemeRestartSubMessage": "您是否要重启?",
|
||||
"DialogFirmwareInstallEmbeddedMessage": "要安装游戏内置的固件吗?(固件 {0})",
|
||||
"DialogFirmwareInstallEmbeddedSuccessMessage": "未找到已安装的固件,但 Ryujinx 可以从现有的游戏安装固件{0}.\\n模拟器现在可以运行。",
|
||||
"DialogFirmwareInstallEmbeddedSuccessMessage": "未找到已安装的固件,但 Ryujinx 可以从现有的游戏安装固件{0}.\n模拟器现在可以运行。",
|
||||
"DialogFirmwareNoFirmwareInstalledMessage": "未安装固件",
|
||||
"DialogFirmwareInstalledMessage": "已安装固件{0}",
|
||||
"DialogOpenSettingsWindowLabel": "打开设置窗口",
|
||||
@ -344,11 +344,11 @@
|
||||
"DialogUserErrorDialogTitle": "Ryujinx 错误 ({0})",
|
||||
"DialogAmiiboApiTitle": "Amiibo API",
|
||||
"DialogAmiiboApiFailFetchMessage": "从 API 获取信息时出错。",
|
||||
"DialogAmiiboApiConnectErrorMessage": "无法连接到 Amiibo API 服务器。服务器可能已关闭,或者您没有网络连接。",
|
||||
"DialogAmiiboApiConnectErrorMessage": "无法连接到 Amiibo API 服务器。服务器可能已关闭,或者您没有连接网络。",
|
||||
"DialogProfileInvalidProfileErrorMessage": "预设{0} 与当前输入配置系统不兼容。",
|
||||
"DialogProfileDefaultProfileOverwriteErrorMessage": "默认预设无法被覆盖",
|
||||
"DialogProfileDefaultProfileOverwriteErrorMessage": "默认预设不能被覆盖",
|
||||
"DialogProfileDeleteProfileTitle": "删除预设",
|
||||
"DialogProfileDeleteProfileMessage": "删除后不可恢复,确定吗?",
|
||||
"DialogProfileDeleteProfileMessage": "删除后不可恢复,确认删除吗?",
|
||||
"DialogWarning": "警告",
|
||||
"DialogPPTCDeletionMessage": "您即将删除:\n\n{0}的 PPTC 缓存\n\n确定吗?",
|
||||
"DialogPPTCDeletionErrorMessage": "清除位于{0}的 PPTC 缓存时出错: {1}",
|
||||
@ -357,10 +357,10 @@
|
||||
"DialogRyujinxErrorMessage": "Ryujinx 遇到错误",
|
||||
"DialogInvalidTitleIdErrorMessage": "UI 错误:所选游戏没有有效的标题ID",
|
||||
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "路径{0}找不到有效的系统固件。",
|
||||
"DialogFirmwareInstallerFirmwareInstallTitle": "安装固件{0}",
|
||||
"DialogFirmwareInstallerFirmwareInstallMessage": "将安装{0}版本的系统。",
|
||||
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\n这将替换当前系统版本{0}。",
|
||||
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n确认进行?",
|
||||
"DialogFirmwareInstallerFirmwareInstallTitle": "固件{0}",
|
||||
"DialogFirmwareInstallerFirmwareInstallMessage": "即将安装系统版本{0}。",
|
||||
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\n会替换当前系统版本{0}。",
|
||||
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n是否确认继续?",
|
||||
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "安装固件中...",
|
||||
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "成功安装系统版本{0}。",
|
||||
"DialogUserProfileDeletionWarningMessage": "删除后将没有可选择的用户账户",
|
||||
@ -377,7 +377,7 @@
|
||||
"DialogLoadAppGameAlreadyLoadedSubMessage": "请停止模拟或关闭程序,再启动另一个游戏。",
|
||||
"DialogUpdateAddUpdateErrorMessage": "选择的文件不包含所选游戏的更新!",
|
||||
"DialogSettingsBackendThreadingWarningTitle": "警告 - 后端多线程",
|
||||
"DialogSettingsBackendThreadingWarningMessage": "改变此选项后必须重启 Ryujinx 才能生效。\\n根据您的硬件,您开启该选项时,可能需要手动禁用驱动程序本身的GL多线程。",
|
||||
"DialogSettingsBackendThreadingWarningMessage": "改变此选项后必须重启 Ryujinx 才能生效。\n\n取决于您的硬件,可能需要手动禁用驱动面板中的线程优化。",
|
||||
"SettingsTabGraphicsFeaturesOptions": "功能",
|
||||
"SettingsTabGraphicsBackendMultithreading": "后端多线程:",
|
||||
"CommonAuto": "自动(推荐)",
|
||||
@ -403,8 +403,8 @@
|
||||
"AmiiboSeriesLabel": "Amiibo 系列",
|
||||
"AmiiboCharacterLabel": "角色",
|
||||
"AmiiboScanButtonLabel": "扫描",
|
||||
"AmiiboOptionsShowAllLabel": "显示所有 Amiibo",
|
||||
"AmiiboOptionsUsRandomTagLabel": "修正:使用随机标记的 Uuid",
|
||||
"AmiiboOptionsShowAllLabel": "显示所有 Amiibo 系列",
|
||||
"AmiiboOptionsUsRandomTagLabel": "修复:使用随机标记的 UUID",
|
||||
"DlcManagerTableHeadingEnabledLabel": "启用",
|
||||
"DlcManagerTableHeadingTitleIdLabel": "游戏ID",
|
||||
"DlcManagerTableHeadingContainerPathLabel": "文件夹路径",
|
||||
@ -416,38 +416,38 @@
|
||||
"CommonFavorite": "收藏",
|
||||
"OrderAscending": "从小到大",
|
||||
"OrderDescending": "从大到小",
|
||||
"SettingsTabGraphicsFeatures": "额外功能和增强",
|
||||
"SettingsTabGraphicsFeatures": "功能与增强",
|
||||
"ErrorWindowTitle": "错误窗口",
|
||||
"ToggleDiscordTooltip": "启用或关闭 Discord 详细在线状态展示",
|
||||
"ToggleDiscordTooltip": "控制是否在 Discord 中显示您的游玩状态",
|
||||
"AddGameDirBoxTooltip": "输入要添加的游戏目录",
|
||||
"AddGameDirTooltip": "添加游戏目录到列表中",
|
||||
"RemoveGameDirTooltip": "移除选中的目录",
|
||||
"CustomThemeCheckTooltip": "启用或关闭自定义主题",
|
||||
"CustomThemeCheckTooltip": "使用自定义UI主题来更改模拟器的外观样式",
|
||||
"CustomThemePathTooltip": "自定义主题的目录",
|
||||
"CustomThemeBrowseTooltip": "查找自定义主题",
|
||||
"DockModeToggleTooltip": "是否开启 Switch 的主机模式",
|
||||
"DirectKeyboardTooltip": "是否开启\"直连键盘访问(HID)支持\"\n(部分游戏可以使用您的键盘输入文字)",
|
||||
"DirectMouseTooltip": "是否开启\"直连鼠标访问(HID)支持\"\n(部分游戏可以使用您的鼠标导航)",
|
||||
"DockModeToggleTooltip": "启用 Switch 的主机模式。\n绝大多数游戏画质会提高,略微增加性能消耗。\n在掌机和主机模式切换的过程中,您可能需要重新设置手柄类型",
|
||||
"DirectKeyboardTooltip": "开启 \"直连键盘访问(HID)支持\"\n(部分游戏可以使用您的键盘输入文字)",
|
||||
"DirectMouseTooltip": "开启 \"直连鼠标访问(HID)支持\"\n(部分游戏可以使用您的鼠标导航)",
|
||||
"RegionTooltip": "更改系统区域",
|
||||
"LanguageTooltip": "更改系统语言",
|
||||
"TimezoneTooltip": "更改系统时区",
|
||||
"TimeTooltip": "更改系统时钟",
|
||||
"VSyncToggleTooltip": "关闭后,部分使用动态帧率的游戏可以超过60Hz的刷新率",
|
||||
"PptcToggleTooltip": "开启以后减少游戏启动时间和卡顿",
|
||||
"FsIntegrityToggleTooltip": "是否检查游戏文件内容的完整性",
|
||||
"VSyncToggleTooltip": "关闭后,小部分游戏可以超过60FPS帧率,以获得高帧率体验。\n但是可能出现软锁或读盘时间增加。\n如不确定或没有需求,请保持选项开启",
|
||||
"PptcToggleTooltip": "缓存编译完成的游戏CPU指令。减少启动时间和卡顿,提高游戏响应速度",
|
||||
"FsIntegrityToggleTooltip": "检查游戏文件内容的完整性。\n遇到损坏的文件则记录到日志文件,有助于排查错误。\n对性能没有影响。",
|
||||
"AudioBackendTooltip": "默认推荐SDL,但每种音频后端对各类游戏兼容性不同,遇到音频问题可以尝试切换后端",
|
||||
"MemoryManagerTooltip": "改变 Switch 内存映射到电脑内存的方式,会影响CPU性能消耗",
|
||||
"MemoryManagerSoftwareTooltip": "使用软件内存页管理,最精确但是速度最慢",
|
||||
"MemoryManagerHostTooltip": "直接映射内存页到电脑内存,JIT效率高",
|
||||
"MemoryManagerUnsafeTooltip": "直接映射内存页,但不检查内存溢出,JIT效率最高。\nRyujinx可以访问任何位置的内存,因而相对不安全。此模式下只应运行您信任的游戏或软件(即官方游戏)",
|
||||
"MemoryManagerUnsafeTooltip": "直接映射内存页,但不检查内存溢出,JIT效率最高。\nRyujinx可以访问任何位置的内存,因而相对不安全。\n此模式下只应运行您信任的游戏或软件(即官方游戏)",
|
||||
"DRamTooltip": "扩展模拟的 Switch 内存为6GB。\n某些高清纹理MOD或4K MOD需要此选项",
|
||||
"IgnoreMissingServicesTooltip": "忽略某些未实现的系统服务,少部分游戏需要此选项才能启动",
|
||||
"IgnoreMissingServicesTooltip": "开启后,游戏会忽略未实现的系统服务,从而继续运行。\n少部分新发布的游戏由于使用新的未知系统服务,可能需要此选项来避免闪退。\n模拟器更新完善系统服务之后,则无需开启选项。\n如您的游戏已经正常运行,请保持此选项关闭",
|
||||
"GraphicsBackendThreadingTooltip": "启用后端多线程",
|
||||
"GalThreadingTooltip": "使用模拟器自带的多线程调度,减少着色器编译的卡顿,并提高驱动程序的性能(尤其是缺失多线程的AMD)。\nNVIDIA用户需要重启模拟器才能禁用驱动本身的多线程,否则您需手动执行禁用获得最佳性能",
|
||||
"ShaderCacheToggleTooltip": "开启后缓存着色器到本地,减少游戏卡顿",
|
||||
"GalThreadingTooltip": "使用模拟器内置的多线程优化,减少着色器编译的卡顿,并提高驱动程序的性能(尤其是缺失多线程的AMD)。\nNVIDIA显卡需要重启模拟器才能禁用驱动本身的线程优化,您也可以手动在控制面板将其禁用",
|
||||
"ShaderCacheToggleTooltip": "开启后,模拟器会保存编译完成的着色器到磁盘,减少游戏渲染新特效和场景时的卡顿",
|
||||
"ResolutionScaleTooltip": "缩放渲染的分辨率",
|
||||
"ResolutionScaleEntryTooltip": "尽量使用例如1.5的浮点倍数。非整数的倍率易引起 BUG",
|
||||
"AnisotropyTooltip": "各向异性过滤等级。提高倾斜视角纹理的清晰度\n('自动'使用游戏默认指定的等级)",
|
||||
"ResolutionScaleEntryTooltip": "尽可能使用例如1.5的浮点倍数。非整数的倍率易引起 BUG",
|
||||
"AnisotropyTooltip": "各向异性过滤等级。提高倾斜视角纹理的清晰度\n('自动'使用游戏默认的等级)",
|
||||
"AspectRatioTooltip": "渲染窗口的宽高比",
|
||||
"ShaderDumpPathTooltip": "转储图形着色器的路径",
|
||||
"FileLogTooltip": "是否保存日志文件到硬盘",
|
||||
@ -478,8 +478,8 @@
|
||||
"AboutRyujinxContributorsButtonHeader": "查看所有参与者",
|
||||
"SettingsTabSystemAudioVolume": "音量: ",
|
||||
"AudioVolumeTooltip": "调节音量",
|
||||
"SettingsTabSystemEnableInternetAccess": "启用网络连接",
|
||||
"EnableInternetAccessTooltip": "开启互联网访问。此选项打开后,效果类似于 Switch 连接到互联网的状态。\n注意即使此选项关闭,应用程序偶尔也有可能连接到网络",
|
||||
"SettingsTabSystemEnableInternetAccess": "允许网络访问/局域网模式",
|
||||
"EnableInternetAccessTooltip": "允许模拟的游戏进程访问互联网。\n当多个模拟器/真实Switch连接到同一个局域网时,带有 LAN 模式的游戏可以相互通信。\n即使开启选项也无法访问 Nintendo 服务器。此外可能导致某些尝试联网的游戏崩溃。\n如果您不确定,请关闭该选项。",
|
||||
"GameListContextMenuManageCheatToolTip": "管理金手指",
|
||||
"GameListContextMenuManageCheat": "管理金手指",
|
||||
"ControllerSettingsStickRange": "范围",
|
||||
@ -494,7 +494,7 @@
|
||||
"DialogUpdaterFlatpakNotSupportedMessage": "请通过 FlatHub 更新 Ryujinx。",
|
||||
"UpdaterDisabledWarningTitle": "更新已禁用!",
|
||||
"GameListContextMenuOpenSdModsDirectory": "打开 Atmosphere MOD 目录",
|
||||
"GameListContextMenuOpenSdModsDirectoryToolTip": "打开包含应用程序 MOD 的额外 Atmosphere SD 卡目录",
|
||||
"GameListContextMenuOpenSdModsDirectoryToolTip": "打开适用于 Atmosphere 自制系统的 MOD 目录",
|
||||
"ControllerSettingsRotate90": "顺时针旋转 90°",
|
||||
"IconSize": "图标尺寸",
|
||||
"IconSizeTooltip": "更改游戏图标大小",
|
||||
@ -508,7 +508,7 @@
|
||||
"UserErrorUndefined": "未定义错误",
|
||||
"UserErrorNoKeysDescription": "Ryujinx 找不到 'prod.keys' 文件",
|
||||
"UserErrorNoFirmwareDescription": "Ryujinx 找不到任何已安装的固件",
|
||||
"UserErrorFirmwareParsingFailedDescription": "Ryujinx 无法解密选择的固件。这通常是由于密钥过旧。",
|
||||
"UserErrorFirmwareParsingFailedDescription": "Ryujinx 无法解密选择的固件。这通常是由于过旧的密钥。",
|
||||
"UserErrorApplicationNotFoundDescription": "Ryujinx 在选中路径找不到有效的应用程序。",
|
||||
"UserErrorUnknownDescription": "发生未知错误!",
|
||||
"UserErrorUndefinedDescription": "发生了未定义错误!此类错误不应出现,请联系开发人员!",
|
||||
@ -518,7 +518,7 @@
|
||||
"RyujinxInfo": "Ryujinx - 信息",
|
||||
"RyujinxConfirm": "Ryujinx - 确认",
|
||||
"FileDialogAllTypes": "全部类型",
|
||||
"Never": "从不",
|
||||
"Never": "从未",
|
||||
"SwkbdMinCharacters": "至少应为 {0} 个字长",
|
||||
"SwkbdMinRangeCharacters": "必须为 {0}-{1} 个字长",
|
||||
"SoftwareKeyboard": "软件键盘",
|
||||
@ -542,7 +542,7 @@
|
||||
"AllKeyboards": "所有键盘",
|
||||
"OpenFileDialogTitle": "选择支持的文件格式",
|
||||
"OpenFolderDialogTitle": "选择一个包含解包游戏的文件夹",
|
||||
"AllSupportedFormats": "全部支持的格式",
|
||||
"AllSupportedFormats": "所有支持的格式",
|
||||
"RyujinxUpdater": "Ryujinx 更新程序",
|
||||
"SettingsTabHotkeys": "快捷键",
|
||||
"SettingsTabHotkeysHotkeys": "键盘快捷键",
|
||||
@ -558,7 +558,7 @@
|
||||
"AvatarWindowTitle": "管理账户 - 头像",
|
||||
"Amiibo": "Amiibo",
|
||||
"Unknown": "未知",
|
||||
"Usage": "使用",
|
||||
"Usage": "扫描可获得",
|
||||
"Writable": "可写入",
|
||||
"SelectDlcDialogTitle": "选择 DLC 文件",
|
||||
"SelectUpdateDialogTitle": "选择更新文件",
|
||||
@ -568,7 +568,25 @@
|
||||
"UpdateWindowTitle": "管理游戏更新",
|
||||
"CheatWindowHeading": "适用于 {0} [{1}] 的金手指",
|
||||
"DlcWindowHeading": "适用于 {0} [{1}] 的 DLC",
|
||||
"UserProfilesEditProfile": "编辑选中账户",
|
||||
"Cancel": "取消",
|
||||
"Save": "保存",
|
||||
"Discard": "返回",
|
||||
"UserProfilesSetProfileImage": "选择头像",
|
||||
"UserProfileEmptyNameError": "必须输入名称",
|
||||
"UserProfileNoImageError": "请选择您的头像",
|
||||
"GameUpdateWindowHeading": "适用于 {0} [{1}] 的更新",
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "分辨率提高",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "降低分辨率"
|
||||
"SettingsTabHotkeysResScaleUpHotkey": "提高分辨率:",
|
||||
"SettingsTabHotkeysResScaleDownHotkey": "降低分辨率:",
|
||||
"UserProfilesName": "名称:",
|
||||
"UserProfilesUserId" : "用户 ID:",
|
||||
"SettingsTabGraphicsBackend": "图形后端",
|
||||
"SettingsTabGraphicsBackendTooltip": "显卡使用的图形后端",
|
||||
"SettingsEnableTextureRecompression": "启用纹理重压缩",
|
||||
"SettingsEnableTextureRecompressionTooltip": "压缩某些纹理以减少显存的使用。\n适合显存小于 4GB 的 GPU开启。\n如果您不确定,请保持此项为关闭。",
|
||||
"SettingsTabGraphicsPreferredGpu": "首选 GPU",
|
||||
"SettingsTabGraphicsPreferredGpuTooltip": "选择Vulkan API使用的显卡。\n此选项不会影响OpenGL API。\n如果您不确定,建议选择\"dGPU(独立显卡)\"。如果没有独立显卡,则无需改动此选项",
|
||||
"SettingsAppRequiredRestartMessage": "Ryujinx 需要重启",
|
||||
"SettingsGpuBackendRestartMessage": "您修改了图形 API 或显卡设置。需要重新启动才能生效",
|
||||
"SettingsGpuBackendRestartSubMessage": "是否重启模拟器?"
|
||||
}
|
||||
|
@ -120,6 +120,7 @@
|
||||
<None Remove="Assets\Locales\it_IT.json" />
|
||||
<None Remove="Assets\Locales\ja_JP.json" />
|
||||
<None Remove="Assets\Locales\ko_KR.json" />
|
||||
<None Remove="Assets\Locales\pl_PL.json" />
|
||||
<None Remove="Assets\Locales\pt_BR.json" />
|
||||
<None Remove="Assets\Locales\ru_RU.json" />
|
||||
<None Remove="Assets\Locales\tr_TR.json" />
|
||||
@ -139,6 +140,7 @@
|
||||
<EmbeddedResource Include="Assets\Locales\it_IT.json" />
|
||||
<EmbeddedResource Include="Assets\Locales\ja_JP.json" />
|
||||
<EmbeddedResource Include="Assets\Locales\ko_KR.json" />
|
||||
<EmbeddedResource Include="Assets\Locales\pl_PL.json" />
|
||||
<EmbeddedResource Include="Assets\Locales\pt_BR.json" />
|
||||
<EmbeddedResource Include="Assets\Locales\ru_RU.json" />
|
||||
<EmbeddedResource Include="Assets\Locales\tr_TR.json" />
|
||||
|
@ -131,56 +131,60 @@
|
||||
<MenuItem Header="{locale:Locale MenuBarOptionsChangeLanguage}">
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="en_US"
|
||||
Header="American English" />
|
||||
CommandParameter="de_DE"
|
||||
Header="Deutsch" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="pt_BR"
|
||||
Header="Brazilian Portuguese" />
|
||||
CommandParameter="en_US"
|
||||
Header="English (US)" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="es_ES"
|
||||
Header="Castilian Spanish" />
|
||||
Header="Español (ES)" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="fr_FR"
|
||||
Header="French" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="de_DE"
|
||||
Header="German" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="el_GR"
|
||||
Header="Greek" />
|
||||
Header="Français" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="it_IT"
|
||||
Header="Italian" />
|
||||
Header="Italiano" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="ja_JP"
|
||||
Header="Japanese" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="ko_KR"
|
||||
Header="Korean" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="ru_RU"
|
||||
Header="Russian" />
|
||||
CommandParameter="pt_BR"
|
||||
Header="Português (BR)" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="tr_TR"
|
||||
Header="Turkish" />
|
||||
Header="Türkçe" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="el_GR"
|
||||
Header="Ελληνικά" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="pl_PL"
|
||||
Header="Polish" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="ru_RU"
|
||||
Header="Русский" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="zh_CN"
|
||||
Header="Simplified Chinese" />
|
||||
Header="简体中文" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="zh_TW"
|
||||
Header="Traditional Chinese (Taiwan)" />
|
||||
Header="繁體中文" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="ja_JP"
|
||||
Header="日本語" />
|
||||
<MenuItem
|
||||
Command="{ReflectionBinding ChangeLanguage}"
|
||||
CommandParameter="ko_KR"
|
||||
Header="한국어" />
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
|
@ -9,19 +9,10 @@ namespace Ryujinx.Common.Collections
|
||||
/// </summary>
|
||||
/// <typeparam name="K">Key</typeparam>
|
||||
/// <typeparam name="V">Value</typeparam>
|
||||
public class IntervalTree<K, V> where K : IComparable<K>
|
||||
public class IntervalTree<K, V> : IntrusiveRedBlackTreeImpl<IntervalTreeNode<K, V>> where K : IComparable<K>
|
||||
{
|
||||
private const int ArrayGrowthSize = 32;
|
||||
|
||||
private const bool Black = true;
|
||||
private const bool Red = false;
|
||||
private IntervalTreeNode<K, V> _root = null;
|
||||
private int _count = 0;
|
||||
|
||||
public int Count => _count;
|
||||
|
||||
public IntervalTree() { }
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
@ -80,7 +71,7 @@ namespace Ryujinx.Common.Collections
|
||||
throw new ArgumentNullException(nameof(end));
|
||||
}
|
||||
|
||||
GetValues(_root, start, end, ref overlaps, ref overlapCount);
|
||||
GetValues(Root, start, end, ref overlaps, ref overlapCount);
|
||||
|
||||
return overlapCount;
|
||||
}
|
||||
@ -128,7 +119,7 @@ namespace Ryujinx.Common.Collections
|
||||
|
||||
int removed = Delete(key, value);
|
||||
|
||||
_count -= removed;
|
||||
Count -= removed;
|
||||
|
||||
return removed;
|
||||
}
|
||||
@ -141,7 +132,7 @@ namespace Ryujinx.Common.Collections
|
||||
{
|
||||
List<RangeNode<K, V>> list = new List<RangeNode<K, V>>();
|
||||
|
||||
AddToList(_root, list);
|
||||
AddToList(Root, list);
|
||||
|
||||
return list;
|
||||
}
|
||||
@ -182,7 +173,7 @@ namespace Ryujinx.Common.Collections
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
|
||||
IntervalTreeNode<K, V> node = _root;
|
||||
IntervalTreeNode<K, V> node = Root;
|
||||
while (node != null)
|
||||
{
|
||||
int cmp = key.CompareTo(node.Start);
|
||||
@ -317,7 +308,7 @@ namespace Ryujinx.Common.Collections
|
||||
private IntervalTreeNode<K, V> BSTInsert(K start, K end, V value)
|
||||
{
|
||||
IntervalTreeNode<K, V> parent = null;
|
||||
IntervalTreeNode<K, V> node = _root;
|
||||
IntervalTreeNode<K, V> node = Root;
|
||||
|
||||
while (node != null)
|
||||
{
|
||||
@ -345,14 +336,14 @@ namespace Ryujinx.Common.Collections
|
||||
}
|
||||
}
|
||||
|
||||
_count++;
|
||||
Count++;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
IntervalTreeNode<K, V> newNode = new IntervalTreeNode<K, V>(start, end, value, parent);
|
||||
if (newNode.Parent == null)
|
||||
{
|
||||
_root = newNode;
|
||||
Root = newNode;
|
||||
}
|
||||
else if (start.CompareTo(parent.Start) < 0)
|
||||
{
|
||||
@ -364,7 +355,7 @@ namespace Ryujinx.Common.Collections
|
||||
}
|
||||
|
||||
PropagateIncrease(newNode);
|
||||
_count++;
|
||||
Count++;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
@ -418,7 +409,7 @@ namespace Ryujinx.Common.Collections
|
||||
|
||||
if (ParentOf(replacementNode) == null)
|
||||
{
|
||||
_root = tmp;
|
||||
Root = tmp;
|
||||
}
|
||||
else if (replacementNode == LeftOf(ParentOf(replacementNode)))
|
||||
{
|
||||
@ -447,295 +438,27 @@ namespace Ryujinx.Common.Collections
|
||||
return removed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the node with the largest key where <paramref name="node"/> is considered the root node.
|
||||
/// </summary>
|
||||
/// <param name="node">Root Node</param>
|
||||
/// <returns>Node with the maximum key in the tree of <paramref name="node"/></returns>
|
||||
private static IntervalTreeNode<K, V> Maximum(IntervalTreeNode<K, V> node)
|
||||
{
|
||||
IntervalTreeNode<K, V> tmp = node;
|
||||
while (tmp.Right != null)
|
||||
{
|
||||
tmp = tmp.Right;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the node whose key is immediately less than <paramref name="node"/>.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to find the predecessor of</param>
|
||||
/// <returns>Predecessor of <paramref name="node"/></returns>
|
||||
private static IntervalTreeNode<K, V> PredecessorOf(IntervalTreeNode<K, V> node)
|
||||
{
|
||||
if (node.Left != null)
|
||||
{
|
||||
return Maximum(node.Left);
|
||||
}
|
||||
IntervalTreeNode<K, V> parent = node.Parent;
|
||||
while (parent != null && node == parent.Left)
|
||||
{
|
||||
node = parent;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Methods (RBL)
|
||||
private void RestoreBalanceAfterRemoval(IntervalTreeNode<K, V> balanceNode)
|
||||
{
|
||||
IntervalTreeNode<K, V> ptr = balanceNode;
|
||||
|
||||
while (ptr != _root && ColorOf(ptr) == Black)
|
||||
{
|
||||
if (ptr == LeftOf(ParentOf(ptr)))
|
||||
{
|
||||
IntervalTreeNode<K, V> sibling = RightOf(ParentOf(ptr));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ptr), Red);
|
||||
RotateLeft(ParentOf(ptr));
|
||||
sibling = RightOf(ParentOf(ptr));
|
||||
}
|
||||
if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(sibling, Red);
|
||||
ptr = ParentOf(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ColorOf(RightOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(LeftOf(sibling), Black);
|
||||
SetColor(sibling, Red);
|
||||
RotateRight(sibling);
|
||||
sibling = RightOf(ParentOf(ptr));
|
||||
}
|
||||
SetColor(sibling, ColorOf(ParentOf(ptr)));
|
||||
SetColor(ParentOf(ptr), Black);
|
||||
SetColor(RightOf(sibling), Black);
|
||||
RotateLeft(ParentOf(ptr));
|
||||
ptr = _root;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IntervalTreeNode<K, V> sibling = LeftOf(ParentOf(ptr));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ptr), Red);
|
||||
RotateRight(ParentOf(ptr));
|
||||
sibling = LeftOf(ParentOf(ptr));
|
||||
}
|
||||
if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(sibling, Red);
|
||||
ptr = ParentOf(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ColorOf(LeftOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(RightOf(sibling), Black);
|
||||
SetColor(sibling, Red);
|
||||
RotateLeft(sibling);
|
||||
sibling = LeftOf(ParentOf(ptr));
|
||||
}
|
||||
SetColor(sibling, ColorOf(ParentOf(ptr)));
|
||||
SetColor(ParentOf(ptr), Black);
|
||||
SetColor(LeftOf(sibling), Black);
|
||||
RotateRight(ParentOf(ptr));
|
||||
ptr = _root;
|
||||
}
|
||||
}
|
||||
}
|
||||
SetColor(ptr, Black);
|
||||
}
|
||||
|
||||
private void RestoreBalanceAfterInsertion(IntervalTreeNode<K, V> balanceNode)
|
||||
{
|
||||
SetColor(balanceNode, Red);
|
||||
while (balanceNode != null && balanceNode != _root && ColorOf(ParentOf(balanceNode)) == Red)
|
||||
{
|
||||
if (ParentOf(balanceNode) == LeftOf(ParentOf(ParentOf(balanceNode))))
|
||||
{
|
||||
IntervalTreeNode<K, V> sibling = RightOf(ParentOf(ParentOf(balanceNode)));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
balanceNode = ParentOf(ParentOf(balanceNode));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (balanceNode == RightOf(ParentOf(balanceNode)))
|
||||
{
|
||||
balanceNode = ParentOf(balanceNode);
|
||||
RotateLeft(balanceNode);
|
||||
}
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
RotateRight(ParentOf(ParentOf(balanceNode)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IntervalTreeNode<K, V> sibling = LeftOf(ParentOf(ParentOf(balanceNode)));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
balanceNode = ParentOf(ParentOf(balanceNode));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (balanceNode == LeftOf(ParentOf(balanceNode)))
|
||||
{
|
||||
balanceNode = ParentOf(balanceNode);
|
||||
RotateRight(balanceNode);
|
||||
}
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
RotateLeft(ParentOf(ParentOf(balanceNode)));
|
||||
}
|
||||
}
|
||||
}
|
||||
SetColor(_root, Black);
|
||||
}
|
||||
|
||||
private void RotateLeft(IntervalTreeNode<K, V> node)
|
||||
protected override void RotateLeft(IntervalTreeNode<K, V> node)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
IntervalTreeNode<K, V> right = RightOf(node);
|
||||
node.Right = LeftOf(right);
|
||||
if (node.Right != null)
|
||||
{
|
||||
node.Right.Parent = node;
|
||||
}
|
||||
IntervalTreeNode<K, V> nodeParent = ParentOf(node);
|
||||
right.Parent = nodeParent;
|
||||
if (nodeParent == null)
|
||||
{
|
||||
_root = right;
|
||||
}
|
||||
else if (node == LeftOf(nodeParent))
|
||||
{
|
||||
nodeParent.Left = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeParent.Right = right;
|
||||
}
|
||||
right.Left = node;
|
||||
node.Parent = right;
|
||||
base.RotateLeft(node);
|
||||
|
||||
PropagateFull(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void RotateRight(IntervalTreeNode<K, V> node)
|
||||
protected override void RotateRight(IntervalTreeNode<K, V> node)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
IntervalTreeNode<K, V> left = LeftOf(node);
|
||||
node.Left = RightOf(left);
|
||||
if (node.Left != null)
|
||||
{
|
||||
node.Left.Parent = node;
|
||||
}
|
||||
IntervalTreeNode<K, V> nodeParent = ParentOf(node);
|
||||
left.Parent = nodeParent;
|
||||
if (nodeParent == null)
|
||||
{
|
||||
_root = left;
|
||||
}
|
||||
else if (node == RightOf(nodeParent))
|
||||
{
|
||||
nodeParent.Right = left;
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeParent.Left = left;
|
||||
}
|
||||
left.Right = node;
|
||||
node.Parent = left;
|
||||
base.RotateRight(node);
|
||||
|
||||
PropagateFull(node);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Safety-Methods
|
||||
|
||||
// These methods save memory by allowing us to forego sentinel nil nodes, as well as serve as protection against NullReferenceExceptions.
|
||||
|
||||
/// <summary>
|
||||
/// Returns the color of <paramref name="node"/>, or Black if it is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node</param>
|
||||
/// <returns>The boolean color of <paramref name="node"/>, or black if null</returns>
|
||||
private static bool ColorOf(IntervalTreeNode<K, V> node)
|
||||
{
|
||||
return node == null || node.Color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the color of <paramref name="node"/> node to <paramref name="color"/>.
|
||||
/// <br></br>
|
||||
/// This method does nothing if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to set the color of</param>
|
||||
/// <param name="color">Color (Boolean)</param>
|
||||
private static void SetColor(IntervalTreeNode<K, V> node, bool color)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
node.Color = color;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method returns the left node of <paramref name="node"/>, or null if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to retrieve the left child from</param>
|
||||
/// <returns>Left child of <paramref name="node"/></returns>
|
||||
private static IntervalTreeNode<K, V> LeftOf(IntervalTreeNode<K, V> node)
|
||||
{
|
||||
return node?.Left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method returns the right node of <paramref name="node"/>, or null if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to retrieve the right child from</param>
|
||||
/// <returns>Right child of <paramref name="node"/></returns>
|
||||
private static IntervalTreeNode<K, V> RightOf(IntervalTreeNode<K, V> node)
|
||||
{
|
||||
return node?.Right;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parent node of <paramref name="node"/>, or null if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to retrieve the parent from</param>
|
||||
/// <returns>Parent of <paramref name="node"/></returns>
|
||||
private static IntervalTreeNode<K, V> ParentOf(IntervalTreeNode<K, V> node)
|
||||
{
|
||||
return node?.Parent;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public bool ContainsKey(K key)
|
||||
{
|
||||
@ -745,12 +468,6 @@ namespace Ryujinx.Common.Collections
|
||||
}
|
||||
return GetNode(key) != null;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_root = null;
|
||||
_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -777,31 +494,29 @@ namespace Ryujinx.Common.Collections
|
||||
/// </summary>
|
||||
/// <typeparam name="K">Key type of the node</typeparam>
|
||||
/// <typeparam name="V">Value type of the node</typeparam>
|
||||
class IntervalTreeNode<K, V>
|
||||
public class IntervalTreeNode<K, V> : IntrusiveRedBlackTreeNode<IntervalTreeNode<K, V>>
|
||||
{
|
||||
public bool Color = true;
|
||||
public IntervalTreeNode<K, V> Left = null;
|
||||
public IntervalTreeNode<K, V> Right = null;
|
||||
public IntervalTreeNode<K, V> Parent = null;
|
||||
|
||||
/// <summary>
|
||||
/// The start of the range.
|
||||
/// </summary>
|
||||
public K Start;
|
||||
internal K Start;
|
||||
|
||||
/// <summary>
|
||||
/// The end of the range - maximum of all in the Values list.
|
||||
/// </summary>
|
||||
public K End;
|
||||
internal K End;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum end value of this node and all its children.
|
||||
/// </summary>
|
||||
public K Max;
|
||||
internal K Max;
|
||||
|
||||
public List<RangeNode<K, V>> Values;
|
||||
/// <summary>
|
||||
/// Values contained on the node that shares a common Start value.
|
||||
/// </summary>
|
||||
internal List<RangeNode<K, V>> Values;
|
||||
|
||||
public IntervalTreeNode(K start, K end, V value, IntervalTreeNode<K, V> parent)
|
||||
internal IntervalTreeNode(K start, K end, V value, IntervalTreeNode<K, V> parent)
|
||||
{
|
||||
Start = start;
|
||||
End = end;
|
||||
|
293
Ryujinx.Common/Collections/IntrusiveRedBlackTree.cs
Normal file
293
Ryujinx.Common/Collections/IntrusiveRedBlackTree.cs
Normal file
@ -0,0 +1,293 @@
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Common.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Tree that provides the ability for O(logN) lookups for keys that exist in the tree, and O(logN) lookups for keys immediately greater than or less than a specified key.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Derived node type</typeparam>
|
||||
public class IntrusiveRedBlackTree<T> : IntrusiveRedBlackTreeImpl<T> where T : IntrusiveRedBlackTreeNode<T>, IComparable<T>
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new node into the tree.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to be added</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
||||
public void Add(T node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(node));
|
||||
}
|
||||
|
||||
Insert(node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a node from the tree.
|
||||
/// </summary>
|
||||
/// <param name="node">Note to be removed</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
||||
public void Remove(T node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(node));
|
||||
}
|
||||
if (Delete(node) != null)
|
||||
{
|
||||
Count--;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the node that is considered equal to the specified node by the comparator.
|
||||
/// </summary>
|
||||
/// <param name="searchNode">Node to compare with</param>
|
||||
/// <returns>Node that is equal to <paramref name="searchNode"/></returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="searchNode"/> is null</exception>
|
||||
public T GetNode(T searchNode)
|
||||
{
|
||||
if (searchNode == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(searchNode));
|
||||
}
|
||||
|
||||
T node = Root;
|
||||
while (node != null)
|
||||
{
|
||||
int cmp = searchNode.CompareTo(node);
|
||||
if (cmp < 0)
|
||||
{
|
||||
node = node.Left;
|
||||
}
|
||||
else if (cmp > 0)
|
||||
{
|
||||
node = node.Right;
|
||||
}
|
||||
else
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods (BST)
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a new node into the tree.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to be inserted</param>
|
||||
private void Insert(T node)
|
||||
{
|
||||
T newNode = BSTInsert(node);
|
||||
RestoreBalanceAfterInsertion(newNode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insertion Mechanism for a Binary Search Tree (BST).
|
||||
/// <br></br>
|
||||
/// Iterates the tree starting from the root and inserts a new node
|
||||
/// where all children in the left subtree are less than <paramref name="newNode"/>,
|
||||
/// and all children in the right subtree are greater than <paramref name="newNode"/>.
|
||||
/// </summary>
|
||||
/// <param name="newNode">Node to be inserted</param>
|
||||
/// <returns>The inserted Node</returns>
|
||||
private T BSTInsert(T newNode)
|
||||
{
|
||||
T parent = null;
|
||||
T node = Root;
|
||||
|
||||
while (node != null)
|
||||
{
|
||||
parent = node;
|
||||
int cmp = newNode.CompareTo(node);
|
||||
if (cmp < 0)
|
||||
{
|
||||
node = node.Left;
|
||||
}
|
||||
else if (cmp > 0)
|
||||
{
|
||||
node = node.Right;
|
||||
}
|
||||
else
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
newNode.Parent = parent;
|
||||
if (parent == null)
|
||||
{
|
||||
Root = newNode;
|
||||
}
|
||||
else if (newNode.CompareTo(parent) < 0)
|
||||
{
|
||||
parent.Left = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.Right = newNode;
|
||||
}
|
||||
Count++;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes <paramref name="nodeToDelete"/> from the tree, if it exists.
|
||||
/// </summary>
|
||||
/// <param name="nodeToDelete">Node to be removed</param>
|
||||
/// <returns>The deleted Node</returns>
|
||||
private T Delete(T nodeToDelete)
|
||||
{
|
||||
if (nodeToDelete == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
T old = nodeToDelete;
|
||||
T child;
|
||||
T parent;
|
||||
bool color;
|
||||
|
||||
if (LeftOf(nodeToDelete) == null)
|
||||
{
|
||||
child = RightOf(nodeToDelete);
|
||||
}
|
||||
else if (RightOf(nodeToDelete) == null)
|
||||
{
|
||||
child = LeftOf(nodeToDelete);
|
||||
}
|
||||
else
|
||||
{
|
||||
T element = Minimum(RightOf(nodeToDelete));
|
||||
|
||||
child = RightOf(element);
|
||||
parent = ParentOf(element);
|
||||
color = ColorOf(element);
|
||||
|
||||
if (child != null)
|
||||
{
|
||||
child.Parent = parent;
|
||||
}
|
||||
|
||||
if (parent == null)
|
||||
{
|
||||
Root = child;
|
||||
}
|
||||
else if (element == LeftOf(parent))
|
||||
{
|
||||
parent.Left = child;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.Right = child;
|
||||
}
|
||||
|
||||
if (ParentOf(element) == old)
|
||||
{
|
||||
parent = element;
|
||||
}
|
||||
|
||||
element.Color = old.Color;
|
||||
element.Left = old.Left;
|
||||
element.Right = old.Right;
|
||||
element.Parent = old.Parent;
|
||||
|
||||
if (ParentOf(old) == null)
|
||||
{
|
||||
Root = element;
|
||||
}
|
||||
else if (old == LeftOf(ParentOf(old)))
|
||||
{
|
||||
ParentOf(old).Left = element;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentOf(old).Right = element;
|
||||
}
|
||||
|
||||
LeftOf(old).Parent = element;
|
||||
|
||||
if (RightOf(old) != null)
|
||||
{
|
||||
RightOf(old).Parent = element;
|
||||
}
|
||||
|
||||
if (child != null && color == Black)
|
||||
{
|
||||
RestoreBalanceAfterRemoval(child);
|
||||
}
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
parent = ParentOf(nodeToDelete);
|
||||
color = ColorOf(nodeToDelete);
|
||||
|
||||
if (child != null)
|
||||
{
|
||||
child.Parent = parent;
|
||||
}
|
||||
|
||||
if (parent == null)
|
||||
{
|
||||
Root = child;
|
||||
}
|
||||
else if (nodeToDelete == LeftOf(parent))
|
||||
{
|
||||
parent.Left = child;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.Right = child;
|
||||
}
|
||||
|
||||
if (child != null && color == Black)
|
||||
{
|
||||
RestoreBalanceAfterRemoval(child);
|
||||
}
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public static class IntrusiveRedBlackTreeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve the node that is considered equal to the key by the comparator.
|
||||
/// </summary>
|
||||
/// <param name="tree">Tree to search at</param>
|
||||
/// <param name="key">Key of the node to be found</param>
|
||||
/// <returns>Node that is equal to <paramref name="key"/></returns>
|
||||
public static N GetNodeByKey<N, K>(this IntrusiveRedBlackTree<N> tree, K key)
|
||||
where N : IntrusiveRedBlackTreeNode<N>, IComparable<N>, IComparable<K>
|
||||
where K : struct
|
||||
{
|
||||
N node = tree.RootNode;
|
||||
while (node != null)
|
||||
{
|
||||
int cmp = node.CompareTo(key);
|
||||
if (cmp < 0)
|
||||
{
|
||||
node = node.Right;
|
||||
}
|
||||
else if (cmp > 0)
|
||||
{
|
||||
node = node.Left;
|
||||
}
|
||||
else
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
356
Ryujinx.Common/Collections/IntrusiveRedBlackTreeImpl.cs
Normal file
356
Ryujinx.Common/Collections/IntrusiveRedBlackTreeImpl.cs
Normal file
@ -0,0 +1,356 @@
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Common.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Tree that provides the ability for O(logN) lookups for keys that exist in the tree, and O(logN) lookups for keys immediately greater than or less than a specified key.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Derived node type</typeparam>
|
||||
public class IntrusiveRedBlackTreeImpl<T> where T : IntrusiveRedBlackTreeNode<T>
|
||||
{
|
||||
protected const bool Black = true;
|
||||
protected const bool Red = false;
|
||||
protected T Root = null;
|
||||
|
||||
internal T RootNode => Root;
|
||||
|
||||
/// <summary>
|
||||
/// Number of nodes on the tree.
|
||||
/// </summary>
|
||||
public int Count { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Removes all nodes on the tree.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
Root = null;
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the node whose key is immediately greater than <paramref name="node"/>.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to find the successor of</param>
|
||||
/// <returns>Successor of <paramref name="node"/></returns>
|
||||
internal static T SuccessorOf(T node)
|
||||
{
|
||||
if (node.Right != null)
|
||||
{
|
||||
return Minimum(node.Right);
|
||||
}
|
||||
T parent = node.Parent;
|
||||
while (parent != null && node == parent.Right)
|
||||
{
|
||||
node = parent;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the node whose key is immediately less than <paramref name="node"/>.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to find the predecessor of</param>
|
||||
/// <returns>Predecessor of <paramref name="node"/></returns>
|
||||
internal static T PredecessorOf(T node)
|
||||
{
|
||||
if (node.Left != null)
|
||||
{
|
||||
return Maximum(node.Left);
|
||||
}
|
||||
T parent = node.Parent;
|
||||
while (parent != null && node == parent.Left)
|
||||
{
|
||||
node = parent;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the node with the largest key where <paramref name="node"/> is considered the root node.
|
||||
/// </summary>
|
||||
/// <param name="node">Root node</param>
|
||||
/// <returns>Node with the maximum key in the tree of <paramref name="node"/></returns>
|
||||
protected static T Maximum(T node)
|
||||
{
|
||||
T tmp = node;
|
||||
while (tmp.Right != null)
|
||||
{
|
||||
tmp = tmp.Right;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the node with the smallest key where <paramref name="node"/> is considered the root node.
|
||||
/// </summary>
|
||||
/// <param name="node">Root node</param>
|
||||
/// <returns>Node with the minimum key in the tree of <paramref name="node"/></returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
||||
protected static T Minimum(T node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(node));
|
||||
}
|
||||
T tmp = node;
|
||||
while (tmp.Left != null)
|
||||
{
|
||||
tmp = tmp.Left;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
protected void RestoreBalanceAfterRemoval(T balanceNode)
|
||||
{
|
||||
T ptr = balanceNode;
|
||||
|
||||
while (ptr != Root && ColorOf(ptr) == Black)
|
||||
{
|
||||
if (ptr == LeftOf(ParentOf(ptr)))
|
||||
{
|
||||
T sibling = RightOf(ParentOf(ptr));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ptr), Red);
|
||||
RotateLeft(ParentOf(ptr));
|
||||
sibling = RightOf(ParentOf(ptr));
|
||||
}
|
||||
if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(sibling, Red);
|
||||
ptr = ParentOf(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ColorOf(RightOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(LeftOf(sibling), Black);
|
||||
SetColor(sibling, Red);
|
||||
RotateRight(sibling);
|
||||
sibling = RightOf(ParentOf(ptr));
|
||||
}
|
||||
SetColor(sibling, ColorOf(ParentOf(ptr)));
|
||||
SetColor(ParentOf(ptr), Black);
|
||||
SetColor(RightOf(sibling), Black);
|
||||
RotateLeft(ParentOf(ptr));
|
||||
ptr = Root;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
T sibling = LeftOf(ParentOf(ptr));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ptr), Red);
|
||||
RotateRight(ParentOf(ptr));
|
||||
sibling = LeftOf(ParentOf(ptr));
|
||||
}
|
||||
if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(sibling, Red);
|
||||
ptr = ParentOf(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ColorOf(LeftOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(RightOf(sibling), Black);
|
||||
SetColor(sibling, Red);
|
||||
RotateLeft(sibling);
|
||||
sibling = LeftOf(ParentOf(ptr));
|
||||
}
|
||||
SetColor(sibling, ColorOf(ParentOf(ptr)));
|
||||
SetColor(ParentOf(ptr), Black);
|
||||
SetColor(LeftOf(sibling), Black);
|
||||
RotateRight(ParentOf(ptr));
|
||||
ptr = Root;
|
||||
}
|
||||
}
|
||||
}
|
||||
SetColor(ptr, Black);
|
||||
}
|
||||
|
||||
protected void RestoreBalanceAfterInsertion(T balanceNode)
|
||||
{
|
||||
SetColor(balanceNode, Red);
|
||||
while (balanceNode != null && balanceNode != Root && ColorOf(ParentOf(balanceNode)) == Red)
|
||||
{
|
||||
if (ParentOf(balanceNode) == LeftOf(ParentOf(ParentOf(balanceNode))))
|
||||
{
|
||||
T sibling = RightOf(ParentOf(ParentOf(balanceNode)));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
balanceNode = ParentOf(ParentOf(balanceNode));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (balanceNode == RightOf(ParentOf(balanceNode)))
|
||||
{
|
||||
balanceNode = ParentOf(balanceNode);
|
||||
RotateLeft(balanceNode);
|
||||
}
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
RotateRight(ParentOf(ParentOf(balanceNode)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
T sibling = LeftOf(ParentOf(ParentOf(balanceNode)));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
balanceNode = ParentOf(ParentOf(balanceNode));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (balanceNode == LeftOf(ParentOf(balanceNode)))
|
||||
{
|
||||
balanceNode = ParentOf(balanceNode);
|
||||
RotateRight(balanceNode);
|
||||
}
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
RotateLeft(ParentOf(ParentOf(balanceNode)));
|
||||
}
|
||||
}
|
||||
}
|
||||
SetColor(Root, Black);
|
||||
}
|
||||
|
||||
protected virtual void RotateLeft(T node)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
T right = RightOf(node);
|
||||
node.Right = LeftOf(right);
|
||||
if (node.Right != null)
|
||||
{
|
||||
node.Right.Parent = node;
|
||||
}
|
||||
T nodeParent = ParentOf(node);
|
||||
right.Parent = nodeParent;
|
||||
if (nodeParent == null)
|
||||
{
|
||||
Root = right;
|
||||
}
|
||||
else if (node == LeftOf(nodeParent))
|
||||
{
|
||||
nodeParent.Left = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeParent.Right = right;
|
||||
}
|
||||
right.Left = node;
|
||||
node.Parent = right;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void RotateRight(T node)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
T left = LeftOf(node);
|
||||
node.Left = RightOf(left);
|
||||
if (node.Left != null)
|
||||
{
|
||||
node.Left.Parent = node;
|
||||
}
|
||||
T nodeParent = ParentOf(node);
|
||||
left.Parent = nodeParent;
|
||||
if (nodeParent == null)
|
||||
{
|
||||
Root = left;
|
||||
}
|
||||
else if (node == RightOf(nodeParent))
|
||||
{
|
||||
nodeParent.Right = left;
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeParent.Left = left;
|
||||
}
|
||||
left.Right = node;
|
||||
node.Parent = left;
|
||||
}
|
||||
}
|
||||
|
||||
#region Safety-Methods
|
||||
|
||||
// These methods save memory by allowing us to forego sentinel nil nodes, as well as serve as protection against NullReferenceExceptions.
|
||||
|
||||
/// <summary>
|
||||
/// Returns the color of <paramref name="node"/>, or Black if it is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node</param>
|
||||
/// <returns>The boolean color of <paramref name="node"/>, or black if null</returns>
|
||||
protected static bool ColorOf(T node)
|
||||
{
|
||||
return node == null || node.Color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the color of <paramref name="node"/> node to <paramref name="color"/>.
|
||||
/// <br></br>
|
||||
/// This method does nothing if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to set the color of</param>
|
||||
/// <param name="color">Color (Boolean)</param>
|
||||
protected static void SetColor(T node, bool color)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
node.Color = color;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method returns the left node of <paramref name="node"/>, or null if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to retrieve the left child from</param>
|
||||
/// <returns>Left child of <paramref name="node"/></returns>
|
||||
protected static T LeftOf(T node)
|
||||
{
|
||||
return node?.Left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method returns the right node of <paramref name="node"/>, or null if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to retrieve the right child from</param>
|
||||
/// <returns>Right child of <paramref name="node"/></returns>
|
||||
protected static T RightOf(T node)
|
||||
{
|
||||
return node?.Right;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parent node of <paramref name="node"/>, or null if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to retrieve the parent from</param>
|
||||
/// <returns>Parent of <paramref name="node"/></returns>
|
||||
protected static T ParentOf(T node)
|
||||
{
|
||||
return node?.Parent;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
16
Ryujinx.Common/Collections/IntrusiveRedBlackTreeNode.cs
Normal file
16
Ryujinx.Common/Collections/IntrusiveRedBlackTreeNode.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace Ryujinx.Common.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a node in the Red-Black Tree.
|
||||
/// </summary>
|
||||
public class IntrusiveRedBlackTreeNode<T> where T : IntrusiveRedBlackTreeNode<T>
|
||||
{
|
||||
internal bool Color = true;
|
||||
internal T Left;
|
||||
internal T Right;
|
||||
internal T Parent;
|
||||
|
||||
public T Predecessor => IntrusiveRedBlackTreeImpl<T>.PredecessorOf((T)this);
|
||||
public T Successor => IntrusiveRedBlackTreeImpl<T>.SuccessorOf((T)this);
|
||||
}
|
||||
}
|
@ -10,14 +10,8 @@ namespace Ryujinx.Common.Collections
|
||||
/// </summary>
|
||||
/// <typeparam name="K">Key</typeparam>
|
||||
/// <typeparam name="V">Value</typeparam>
|
||||
public class TreeDictionary<K, V> : IDictionary<K, V> where K : IComparable<K>
|
||||
public class TreeDictionary<K, V> : IntrusiveRedBlackTreeImpl<Node<K, V>>, IDictionary<K, V> where K : IComparable<K>
|
||||
{
|
||||
private const bool Black = true;
|
||||
private const bool Red = false;
|
||||
private Node<K, V> _root = null;
|
||||
private int _count = 0;
|
||||
public TreeDictionary() { }
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
@ -57,7 +51,7 @@ namespace Ryujinx.Common.Collections
|
||||
{
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
if (null == value)
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
@ -78,7 +72,7 @@ namespace Ryujinx.Common.Collections
|
||||
}
|
||||
if (Delete(key) != null)
|
||||
{
|
||||
_count--;
|
||||
Count--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,13 +154,12 @@ namespace Ryujinx.Common.Collections
|
||||
|
||||
Queue<Node<K, V>> nodes = new Queue<Node<K, V>>();
|
||||
|
||||
if (this._root != null)
|
||||
if (this.Root != null)
|
||||
{
|
||||
nodes.Enqueue(this._root);
|
||||
nodes.Enqueue(this.Root);
|
||||
}
|
||||
while (nodes.Count > 0)
|
||||
while (nodes.TryDequeue(out Node<K, V> node))
|
||||
{
|
||||
Node<K, V> node = nodes.Dequeue();
|
||||
list.Add(new KeyValuePair<K, V>(node.Key, node.Value));
|
||||
if (node.Left != null)
|
||||
{
|
||||
@ -188,7 +181,7 @@ namespace Ryujinx.Common.Collections
|
||||
{
|
||||
List<KeyValuePair<K, V>> list = new List<KeyValuePair<K, V>>();
|
||||
|
||||
AddToList(_root, list);
|
||||
AddToList(Root, list);
|
||||
|
||||
return list;
|
||||
}
|
||||
@ -229,7 +222,7 @@ namespace Ryujinx.Common.Collections
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
|
||||
Node<K, V> node = _root;
|
||||
Node<K, V> node = Root;
|
||||
while (node != null)
|
||||
{
|
||||
int cmp = key.CompareTo(node.Key);
|
||||
@ -275,7 +268,7 @@ namespace Ryujinx.Common.Collections
|
||||
private Node<K, V> BSTInsert(K key, V value)
|
||||
{
|
||||
Node<K, V> parent = null;
|
||||
Node<K, V> node = _root;
|
||||
Node<K, V> node = Root;
|
||||
|
||||
while (node != null)
|
||||
{
|
||||
@ -298,7 +291,7 @@ namespace Ryujinx.Common.Collections
|
||||
Node<K, V> newNode = new Node<K, V>(key, value, parent);
|
||||
if (newNode.Parent == null)
|
||||
{
|
||||
_root = newNode;
|
||||
Root = newNode;
|
||||
}
|
||||
else if (key.CompareTo(parent.Key) < 0)
|
||||
{
|
||||
@ -308,7 +301,7 @@ namespace Ryujinx.Common.Collections
|
||||
{
|
||||
parent.Right = newNode;
|
||||
}
|
||||
_count++;
|
||||
Count++;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
@ -344,9 +337,8 @@ namespace Ryujinx.Common.Collections
|
||||
|
||||
if (ParentOf(replacementNode) == null)
|
||||
{
|
||||
_root = tmp;
|
||||
Root = tmp;
|
||||
}
|
||||
|
||||
else if (replacementNode == LeftOf(ParentOf(replacementNode)))
|
||||
{
|
||||
ParentOf(replacementNode).Left = tmp;
|
||||
@ -370,43 +362,6 @@ namespace Ryujinx.Common.Collections
|
||||
return replacementNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the node with the largest key where <paramref name="node"/> is considered the root node.
|
||||
/// </summary>
|
||||
/// <param name="node">Root Node</param>
|
||||
/// <returns>Node with the maximum key in the tree of <paramref name="node"/></returns>
|
||||
private static Node<K, V> Maximum(Node<K, V> node)
|
||||
{
|
||||
Node<K, V> tmp = node;
|
||||
while (tmp.Right != null)
|
||||
{
|
||||
tmp = tmp.Right;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the node with the smallest key where <paramref name="node"/> is considered the root node.
|
||||
/// </summary>
|
||||
/// <param name="node">Root Node</param>
|
||||
/// <returns>Node with the minimum key in the tree of <paramref name="node"/></returns>
|
||||
///<exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
||||
private static Node<K, V> Minimum(Node<K, V> node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(node));
|
||||
}
|
||||
Node<K, V> tmp = node;
|
||||
while (tmp.Left != null)
|
||||
{
|
||||
tmp = tmp.Left;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the node whose key immediately less than or equal to <paramref name="key"/>.
|
||||
/// </summary>
|
||||
@ -419,7 +374,7 @@ namespace Ryujinx.Common.Collections
|
||||
{
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
Node<K, V> tmp = _root;
|
||||
Node<K, V> tmp = Root;
|
||||
|
||||
while (tmp != null)
|
||||
{
|
||||
@ -473,7 +428,7 @@ namespace Ryujinx.Common.Collections
|
||||
{
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
Node<K, V> tmp = _root;
|
||||
Node<K, V> tmp = Root;
|
||||
|
||||
while (tmp != null)
|
||||
{
|
||||
@ -515,294 +470,6 @@ namespace Ryujinx.Common.Collections
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the node with the key is immediately greater than <paramref name="node"/>.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to find the successor of</param>
|
||||
/// <returns>Successor of <paramref name="node"/></returns>
|
||||
private static Node<K, V> SuccessorOf(Node<K, V> node)
|
||||
{
|
||||
if (node.Right != null)
|
||||
{
|
||||
return Minimum(node.Right);
|
||||
}
|
||||
Node<K, V> parent = node.Parent;
|
||||
while (parent != null && node == parent.Right)
|
||||
{
|
||||
node = parent;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the node whose key is immediately less than <paramref name="node"/>.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to find the predecessor of</param>
|
||||
/// <returns>Predecessor of <paramref name="node"/></returns>
|
||||
private static Node<K, V> PredecessorOf(Node<K, V> node)
|
||||
{
|
||||
if (node.Left != null)
|
||||
{
|
||||
return Maximum(node.Left);
|
||||
}
|
||||
Node<K, V> parent = node.Parent;
|
||||
while (parent != null && node == parent.Left)
|
||||
{
|
||||
node = parent;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods (RBL)
|
||||
|
||||
private void RestoreBalanceAfterRemoval(Node<K, V> balanceNode)
|
||||
{
|
||||
Node<K, V> ptr = balanceNode;
|
||||
|
||||
while (ptr != _root && ColorOf(ptr) == Black)
|
||||
{
|
||||
if (ptr == LeftOf(ParentOf(ptr)))
|
||||
{
|
||||
Node<K, V> sibling = RightOf(ParentOf(ptr));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ptr), Red);
|
||||
RotateLeft(ParentOf(ptr));
|
||||
sibling = RightOf(ParentOf(ptr));
|
||||
}
|
||||
if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(sibling, Red);
|
||||
ptr = ParentOf(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ColorOf(RightOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(LeftOf(sibling), Black);
|
||||
SetColor(sibling, Red);
|
||||
RotateRight(sibling);
|
||||
sibling = RightOf(ParentOf(ptr));
|
||||
}
|
||||
SetColor(sibling, ColorOf(ParentOf(ptr)));
|
||||
SetColor(ParentOf(ptr), Black);
|
||||
SetColor(RightOf(sibling), Black);
|
||||
RotateLeft(ParentOf(ptr));
|
||||
ptr = _root;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Node<K, V> sibling = LeftOf(ParentOf(ptr));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ptr), Red);
|
||||
RotateRight(ParentOf(ptr));
|
||||
sibling = LeftOf(ParentOf(ptr));
|
||||
}
|
||||
if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(sibling, Red);
|
||||
ptr = ParentOf(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ColorOf(LeftOf(sibling)) == Black)
|
||||
{
|
||||
SetColor(RightOf(sibling), Black);
|
||||
SetColor(sibling, Red);
|
||||
RotateLeft(sibling);
|
||||
sibling = LeftOf(ParentOf(ptr));
|
||||
}
|
||||
SetColor(sibling, ColorOf(ParentOf(ptr)));
|
||||
SetColor(ParentOf(ptr), Black);
|
||||
SetColor(LeftOf(sibling), Black);
|
||||
RotateRight(ParentOf(ptr));
|
||||
ptr = _root;
|
||||
}
|
||||
}
|
||||
}
|
||||
SetColor(ptr, Black);
|
||||
}
|
||||
|
||||
private void RestoreBalanceAfterInsertion(Node<K, V> balanceNode)
|
||||
{
|
||||
SetColor(balanceNode, Red);
|
||||
while (balanceNode != null && balanceNode != _root && ColorOf(ParentOf(balanceNode)) == Red)
|
||||
{
|
||||
if (ParentOf(balanceNode) == LeftOf(ParentOf(ParentOf(balanceNode))))
|
||||
{
|
||||
Node<K, V> sibling = RightOf(ParentOf(ParentOf(balanceNode)));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
balanceNode = ParentOf(ParentOf(balanceNode));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (balanceNode == RightOf(ParentOf(balanceNode)))
|
||||
{
|
||||
balanceNode = ParentOf(balanceNode);
|
||||
RotateLeft(balanceNode);
|
||||
}
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
RotateRight(ParentOf(ParentOf(balanceNode)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Node<K, V> sibling = LeftOf(ParentOf(ParentOf(balanceNode)));
|
||||
|
||||
if (ColorOf(sibling) == Red)
|
||||
{
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(sibling, Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
balanceNode = ParentOf(ParentOf(balanceNode));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (balanceNode == LeftOf(ParentOf(balanceNode)))
|
||||
{
|
||||
balanceNode = ParentOf(balanceNode);
|
||||
RotateRight(balanceNode);
|
||||
}
|
||||
SetColor(ParentOf(balanceNode), Black);
|
||||
SetColor(ParentOf(ParentOf(balanceNode)), Red);
|
||||
RotateLeft(ParentOf(ParentOf(balanceNode)));
|
||||
}
|
||||
}
|
||||
}
|
||||
SetColor(_root, Black);
|
||||
}
|
||||
|
||||
private void RotateLeft(Node<K, V> node)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
Node<K, V> right = RightOf(node);
|
||||
node.Right = LeftOf(right);
|
||||
if (LeftOf(right) != null)
|
||||
{
|
||||
LeftOf(right).Parent = node;
|
||||
}
|
||||
right.Parent = ParentOf(node);
|
||||
if (ParentOf(node) == null)
|
||||
{
|
||||
_root = right;
|
||||
}
|
||||
else if (node == LeftOf(ParentOf(node)))
|
||||
{
|
||||
ParentOf(node).Left = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentOf(node).Right = right;
|
||||
}
|
||||
right.Left = node;
|
||||
node.Parent = right;
|
||||
}
|
||||
}
|
||||
|
||||
private void RotateRight(Node<K, V> node)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
Node<K, V> left = LeftOf(node);
|
||||
node.Left = RightOf(left);
|
||||
if (RightOf(left) != null)
|
||||
{
|
||||
RightOf(left).Parent = node;
|
||||
}
|
||||
left.Parent = node.Parent;
|
||||
if (ParentOf(node) == null)
|
||||
{
|
||||
_root = left;
|
||||
}
|
||||
else if (node == RightOf(ParentOf(node)))
|
||||
{
|
||||
ParentOf(node).Right = left;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentOf(node).Left = left;
|
||||
}
|
||||
left.Right = node;
|
||||
node.Parent = left;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Safety-Methods
|
||||
|
||||
// These methods save memory by allowing us to forego sentinel nil nodes, as well as serve as protection against NullReferenceExceptions.
|
||||
|
||||
/// <summary>
|
||||
/// Returns the color of <paramref name="node"/>, or Black if it is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node</param>
|
||||
/// <returns>The boolean color of <paramref name="node"/>, or black if null</returns>
|
||||
private static bool ColorOf(Node<K, V> node)
|
||||
{
|
||||
return node == null || node.Color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the color of <paramref name="node"/> node to <paramref name="color"/>.
|
||||
/// <br></br>
|
||||
/// This method does nothing if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to set the color of</param>
|
||||
/// <param name="color">Color (Boolean)</param>
|
||||
private static void SetColor(Node<K, V> node, bool color)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
node.Color = color;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method returns the left node of <paramref name="node"/>, or null if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to retrieve the left child from</param>
|
||||
/// <returns>Left child of <paramref name="node"/></returns>
|
||||
private static Node<K, V> LeftOf(Node<K, V> node)
|
||||
{
|
||||
return node?.Left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method returns the right node of <paramref name="node"/>, or null if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to retrieve the right child from</param>
|
||||
/// <returns>Right child of <paramref name="node"/></returns>
|
||||
private static Node<K, V> RightOf(Node<K, V> node)
|
||||
{
|
||||
return node?.Right;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parent node of <paramref name="node"/>, or null if <paramref name="node"/> is null.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to retrieve the parent from</param>
|
||||
/// <returns>Parent of <paramref name="node"/></returns>
|
||||
private static Node<K, V> ParentOf(Node<K, V> node)
|
||||
{
|
||||
return node?.Parent;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Interface Implementations
|
||||
@ -819,9 +486,9 @@ namespace Ryujinx.Common.Collections
|
||||
|
||||
bool IDictionary<K, V>.Remove(K key)
|
||||
{
|
||||
int count = _count;
|
||||
int count = Count;
|
||||
Remove(key);
|
||||
return count > _count;
|
||||
return count > Count;
|
||||
}
|
||||
|
||||
public bool TryGetValue(K key, [MaybeNullWhen(false)] out V value)
|
||||
@ -845,12 +512,6 @@ namespace Ryujinx.Common.Collections
|
||||
Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_root = null;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<K, V> item)
|
||||
{
|
||||
if (item.Key == null)
|
||||
@ -895,9 +556,9 @@ namespace Ryujinx.Common.Collections
|
||||
|
||||
if (node.Value.Equals(item.Value))
|
||||
{
|
||||
int count = _count;
|
||||
int count = Count;
|
||||
Remove(item.Key);
|
||||
return count > _count;
|
||||
return count > Count;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -913,8 +574,6 @@ namespace Ryujinx.Common.Collections
|
||||
return GetKeyValues().GetEnumerator();
|
||||
}
|
||||
|
||||
public int Count => _count;
|
||||
|
||||
public ICollection<K> Keys => GetKeyValues().Keys;
|
||||
|
||||
public ICollection<V> Values => GetKeyValues().Values;
|
||||
@ -928,6 +587,7 @@ namespace Ryujinx.Common.Collections
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Interface Helper Methods
|
||||
|
||||
/// <summary>
|
||||
@ -938,14 +598,13 @@ namespace Ryujinx.Common.Collections
|
||||
{
|
||||
SortedList<K, V> set = new SortedList<K, V>();
|
||||
Queue<Node<K, V>> queue = new Queue<Node<K, V>>();
|
||||
if (_root != null)
|
||||
if (Root != null)
|
||||
{
|
||||
queue.Enqueue(_root);
|
||||
queue.Enqueue(Root);
|
||||
}
|
||||
|
||||
while (queue.Count > 0)
|
||||
while (queue.TryDequeue(out Node<K, V> node))
|
||||
{
|
||||
Node<K, V> node = queue.Dequeue();
|
||||
set.Add(node.Key, node.Value);
|
||||
if (null != node.Left)
|
||||
{
|
||||
@ -959,6 +618,7 @@ namespace Ryujinx.Common.Collections
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@ -967,16 +627,12 @@ namespace Ryujinx.Common.Collections
|
||||
/// </summary>
|
||||
/// <typeparam name="K">Key of the node</typeparam>
|
||||
/// <typeparam name="V">Value of the node</typeparam>
|
||||
class Node<K, V>
|
||||
public class Node<K, V> : IntrusiveRedBlackTreeNode<Node<K, V>> where K : IComparable<K>
|
||||
{
|
||||
public bool Color = true;
|
||||
public Node<K, V> Left = null;
|
||||
public Node<K, V> Right = null;
|
||||
public Node<K, V> Parent = null;
|
||||
public K Key;
|
||||
public V Value;
|
||||
internal K Key;
|
||||
internal V Value;
|
||||
|
||||
public Node(K key, V value, Node<K, V> parent)
|
||||
internal Node(K key, V value, Node<K, V> parent)
|
||||
{
|
||||
Key = key;
|
||||
Value = value;
|
||||
|
@ -274,7 +274,8 @@ namespace Ryujinx.Cpu.Jit
|
||||
/// <inheritdoc/>
|
||||
public void Write(ulong va, ReadOnlySpan<byte> data)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
SignalMemoryTracking(va, (ulong)data.Length, write: true);
|
||||
|
||||
_addressSpaceMirror.Write(va, data);
|
||||
|
@ -26,6 +26,7 @@ namespace Ryujinx.Graphics.GAL
|
||||
public readonly bool SupportsNonConstantTextureOffset;
|
||||
public readonly bool SupportsShaderBallot;
|
||||
public readonly bool SupportsTextureShadowLod;
|
||||
public readonly bool SupportsViewportIndex;
|
||||
public readonly bool SupportsViewportSwizzle;
|
||||
public readonly bool SupportsIndirectParameters;
|
||||
|
||||
@ -59,6 +60,7 @@ namespace Ryujinx.Graphics.GAL
|
||||
bool supportsNonConstantTextureOffset,
|
||||
bool supportsShaderBallot,
|
||||
bool supportsTextureShadowLod,
|
||||
bool supportsViewportIndex,
|
||||
bool supportsViewportSwizzle,
|
||||
bool supportsIndirectParameters,
|
||||
uint maximumUniformBuffersPerStage,
|
||||
@ -89,6 +91,7 @@ namespace Ryujinx.Graphics.GAL
|
||||
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
|
||||
SupportsShaderBallot = supportsShaderBallot;
|
||||
SupportsTextureShadowLod = supportsTextureShadowLod;
|
||||
SupportsViewportIndex = supportsViewportIndex;
|
||||
SupportsViewportSwizzle = supportsViewportSwizzle;
|
||||
SupportsIndirectParameters = supportsIndirectParameters;
|
||||
MaximumUniformBuffersPerStage = maximumUniformBuffersPerStage;
|
||||
|
@ -151,6 +151,190 @@ namespace Ryujinx.Graphics.GAL
|
||||
|
||||
public static class FormatExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// The largest scalar size for a buffer format.
|
||||
/// </summary>
|
||||
public const int MaxBufferFormatScalarSize = 4;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the byte size for a single component of this format, or its packed size.
|
||||
/// </summary>
|
||||
/// <param name="format">Texture format</param>
|
||||
/// <returns>Byte size for a single component, or packed size</returns>
|
||||
public static int GetScalarSize(this Format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Format.R8Unorm:
|
||||
case Format.R8Snorm:
|
||||
case Format.R8Uint:
|
||||
case Format.R8Sint:
|
||||
case Format.R8G8Unorm:
|
||||
case Format.R8G8Snorm:
|
||||
case Format.R8G8Uint:
|
||||
case Format.R8G8Sint:
|
||||
case Format.R8G8B8Unorm:
|
||||
case Format.R8G8B8Snorm:
|
||||
case Format.R8G8B8Uint:
|
||||
case Format.R8G8B8Sint:
|
||||
case Format.R8G8B8A8Unorm:
|
||||
case Format.R8G8B8A8Snorm:
|
||||
case Format.R8G8B8A8Uint:
|
||||
case Format.R8G8B8A8Sint:
|
||||
case Format.R8G8B8A8Srgb:
|
||||
case Format.R4G4Unorm:
|
||||
case Format.R8Uscaled:
|
||||
case Format.R8Sscaled:
|
||||
case Format.R8G8Uscaled:
|
||||
case Format.R8G8Sscaled:
|
||||
case Format.R8G8B8Uscaled:
|
||||
case Format.R8G8B8Sscaled:
|
||||
case Format.R8G8B8A8Uscaled:
|
||||
case Format.R8G8B8A8Sscaled:
|
||||
case Format.B8G8R8A8Unorm:
|
||||
case Format.B8G8R8A8Srgb:
|
||||
return 1;
|
||||
|
||||
case Format.R16Float:
|
||||
case Format.R16Unorm:
|
||||
case Format.R16Snorm:
|
||||
case Format.R16Uint:
|
||||
case Format.R16Sint:
|
||||
case Format.R16G16Float:
|
||||
case Format.R16G16Unorm:
|
||||
case Format.R16G16Snorm:
|
||||
case Format.R16G16Uint:
|
||||
case Format.R16G16Sint:
|
||||
case Format.R16G16B16Float:
|
||||
case Format.R16G16B16Unorm:
|
||||
case Format.R16G16B16Snorm:
|
||||
case Format.R16G16B16Uint:
|
||||
case Format.R16G16B16Sint:
|
||||
case Format.R16G16B16A16Float:
|
||||
case Format.R16G16B16A16Unorm:
|
||||
case Format.R16G16B16A16Snorm:
|
||||
case Format.R16G16B16A16Uint:
|
||||
case Format.R16G16B16A16Sint:
|
||||
case Format.R4G4B4A4Unorm:
|
||||
case Format.R5G5B5X1Unorm:
|
||||
case Format.R5G5B5A1Unorm:
|
||||
case Format.R5G6B5Unorm:
|
||||
case Format.R16Uscaled:
|
||||
case Format.R16Sscaled:
|
||||
case Format.R16G16Uscaled:
|
||||
case Format.R16G16Sscaled:
|
||||
case Format.R16G16B16Uscaled:
|
||||
case Format.R16G16B16Sscaled:
|
||||
case Format.R16G16B16A16Uscaled:
|
||||
case Format.R16G16B16A16Sscaled:
|
||||
case Format.B5G6R5Unorm:
|
||||
case Format.B5G5R5A1Unorm:
|
||||
case Format.A1B5G5R5Unorm:
|
||||
return 2;
|
||||
|
||||
case Format.R32Float:
|
||||
case Format.R32Uint:
|
||||
case Format.R32Sint:
|
||||
case Format.R32G32Float:
|
||||
case Format.R32G32Uint:
|
||||
case Format.R32G32Sint:
|
||||
case Format.R32G32B32Float:
|
||||
case Format.R32G32B32Uint:
|
||||
case Format.R32G32B32Sint:
|
||||
case Format.R32G32B32A32Float:
|
||||
case Format.R32G32B32A32Uint:
|
||||
case Format.R32G32B32A32Sint:
|
||||
case Format.R10G10B10A2Unorm:
|
||||
case Format.R10G10B10A2Uint:
|
||||
case Format.R11G11B10Float:
|
||||
case Format.R9G9B9E5Float:
|
||||
case Format.R32Uscaled:
|
||||
case Format.R32Sscaled:
|
||||
case Format.R32G32Uscaled:
|
||||
case Format.R32G32Sscaled:
|
||||
case Format.R32G32B32Uscaled:
|
||||
case Format.R32G32B32Sscaled:
|
||||
case Format.R32G32B32A32Uscaled:
|
||||
case Format.R32G32B32A32Sscaled:
|
||||
case Format.R10G10B10A2Snorm:
|
||||
case Format.R10G10B10A2Sint:
|
||||
case Format.R10G10B10A2Uscaled:
|
||||
case Format.R10G10B10A2Sscaled:
|
||||
return 4;
|
||||
|
||||
case Format.S8Uint:
|
||||
return 1;
|
||||
case Format.D16Unorm:
|
||||
return 2;
|
||||
case Format.S8UintD24Unorm:
|
||||
case Format.D32Float:
|
||||
case Format.D24UnormS8Uint:
|
||||
return 4;
|
||||
case Format.D32FloatS8Uint:
|
||||
return 8;
|
||||
|
||||
case Format.Bc1RgbaUnorm:
|
||||
case Format.Bc1RgbaSrgb:
|
||||
return 8;
|
||||
|
||||
case Format.Bc2Unorm:
|
||||
case Format.Bc3Unorm:
|
||||
case Format.Bc2Srgb:
|
||||
case Format.Bc3Srgb:
|
||||
case Format.Bc4Unorm:
|
||||
case Format.Bc4Snorm:
|
||||
case Format.Bc5Unorm:
|
||||
case Format.Bc5Snorm:
|
||||
case Format.Bc7Unorm:
|
||||
case Format.Bc7Srgb:
|
||||
case Format.Bc6HSfloat:
|
||||
case Format.Bc6HUfloat:
|
||||
return 16;
|
||||
|
||||
case Format.Etc2RgbUnorm:
|
||||
case Format.Etc2RgbPtaUnorm:
|
||||
case Format.Etc2RgbSrgb:
|
||||
case Format.Etc2RgbPtaSrgb:
|
||||
return 8;
|
||||
|
||||
case Format.Etc2RgbaUnorm:
|
||||
case Format.Etc2RgbaSrgb:
|
||||
return 16;
|
||||
|
||||
case Format.Astc4x4Unorm:
|
||||
case Format.Astc5x4Unorm:
|
||||
case Format.Astc5x5Unorm:
|
||||
case Format.Astc6x5Unorm:
|
||||
case Format.Astc6x6Unorm:
|
||||
case Format.Astc8x5Unorm:
|
||||
case Format.Astc8x6Unorm:
|
||||
case Format.Astc8x8Unorm:
|
||||
case Format.Astc10x5Unorm:
|
||||
case Format.Astc10x6Unorm:
|
||||
case Format.Astc10x8Unorm:
|
||||
case Format.Astc10x10Unorm:
|
||||
case Format.Astc12x10Unorm:
|
||||
case Format.Astc12x12Unorm:
|
||||
case Format.Astc4x4Srgb:
|
||||
case Format.Astc5x4Srgb:
|
||||
case Format.Astc5x5Srgb:
|
||||
case Format.Astc6x5Srgb:
|
||||
case Format.Astc6x6Srgb:
|
||||
case Format.Astc8x5Srgb:
|
||||
case Format.Astc8x6Srgb:
|
||||
case Format.Astc8x8Srgb:
|
||||
case Format.Astc10x5Srgb:
|
||||
case Format.Astc10x6Srgb:
|
||||
case Format.Astc10x8Srgb:
|
||||
case Format.Astc10x10Srgb:
|
||||
case Format.Astc12x10Srgb:
|
||||
case Format.Astc12x12Srgb:
|
||||
return 16;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the texture format is valid to use as image format.
|
||||
/// </summary>
|
||||
|
@ -19,6 +19,7 @@ namespace Ryujinx.Graphics.GAL
|
||||
|
||||
void SetData(ReadOnlySpan<byte> data);
|
||||
void SetData(ReadOnlySpan<byte> data, int layer, int level);
|
||||
void SetData(ReadOnlySpan<byte> data, int layer, int level, Rectangle<int> region);
|
||||
void SetStorage(BufferRange buffer);
|
||||
void Release();
|
||||
}
|
||||
|
@ -113,6 +113,8 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||
TextureSetDataCommand.Run(ref GetCommand<TextureSetDataCommand>(memory), threaded, renderer);
|
||||
_lookup[(int)CommandType.TextureSetDataSlice] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) =>
|
||||
TextureSetDataSliceCommand.Run(ref GetCommand<TextureSetDataSliceCommand>(memory), threaded, renderer);
|
||||
_lookup[(int)CommandType.TextureSetDataSliceRegion] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) =>
|
||||
TextureSetDataSliceRegionCommand.Run(ref GetCommand<TextureSetDataSliceRegionCommand>(memory), threaded, renderer);
|
||||
_lookup[(int)CommandType.TextureSetStorage] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) =>
|
||||
TextureSetStorageCommand.Run(ref GetCommand<TextureSetStorageCommand>(memory), threaded, renderer);
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
TextureRelease,
|
||||
TextureSetData,
|
||||
TextureSetDataSlice,
|
||||
TextureSetDataSliceRegion,
|
||||
TextureSetStorage,
|
||||
|
||||
WindowPresent,
|
||||
|
@ -0,0 +1,31 @@
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureSetDataSliceRegionCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureSetDataSliceRegion;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<byte[]> _data;
|
||||
private int _layer;
|
||||
private int _level;
|
||||
private Rectangle<int> _region;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<byte[]> data, int layer, int level, Rectangle<int> region)
|
||||
{
|
||||
_texture = texture;
|
||||
_data = data;
|
||||
_layer = layer;
|
||||
_level = level;
|
||||
_region = region;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureSetDataSliceRegionCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedTexture texture = command._texture.Get(threaded);
|
||||
texture.Base.SetData(new ReadOnlySpan<byte>(command._data.Get(threaded)), command._layer, command._level, command._region);
|
||||
}
|
||||
}
|
||||
}
|
@ -119,6 +119,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||
_renderer.QueueCommand();
|
||||
}
|
||||
|
||||
public void SetData(ReadOnlySpan<byte> data, int layer, int level, Rectangle<int> region)
|
||||
{
|
||||
_renderer.New<TextureSetDataSliceRegionCommand>().Set(Ref(this), Ref(data.ToArray()), layer, level, region);
|
||||
_renderer.QueueCommand();
|
||||
}
|
||||
|
||||
public void SetStorage(BufferRange buffer)
|
||||
{
|
||||
_renderer.New<TextureSetStorageCommand>().Set(Ref(this), buffer);
|
||||
|
@ -224,7 +224,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
xCount,
|
||||
yCount,
|
||||
dstLinear,
|
||||
dst.MemoryLayout);
|
||||
dst.MemoryLayout.UnpackGobBlocksInY(),
|
||||
dst.MemoryLayout.UnpackGobBlocksInZ());
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
|
@ -29,6 +29,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||
private int _dstHeight;
|
||||
private int _dstStride;
|
||||
private int _dstGobBlocksInY;
|
||||
private int _dstGobBlocksInZ;
|
||||
private int _lineLengthIn;
|
||||
private int _lineCount;
|
||||
|
||||
@ -117,6 +118,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||
_dstHeight = (int)state.SetDstHeight;
|
||||
_dstStride = (int)state.PitchOut;
|
||||
_dstGobBlocksInY = 1 << (int)state.SetDstBlockSizeHeight;
|
||||
_dstGobBlocksInZ = 1 << (int)state.SetDstBlockSizeDepth;
|
||||
_lineLengthIn = (int)state.LineLengthIn;
|
||||
_lineCount = (int)state.LineCount;
|
||||
|
||||
@ -176,6 +178,31 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Verify if the destination X/Y and width/height are taken into account
|
||||
// for linear texture transfers. If not, we can use the fast path for that aswell.
|
||||
// Right now the copy code at the bottom assumes that it is used on both which might be incorrect.
|
||||
if (!_isLinear)
|
||||
{
|
||||
var target = memoryManager.Physical.TextureCache.FindTexture(
|
||||
memoryManager,
|
||||
_dstGpuVa,
|
||||
1,
|
||||
_dstStride,
|
||||
_dstHeight,
|
||||
_lineLengthIn,
|
||||
_lineCount,
|
||||
_isLinear,
|
||||
_dstGobBlocksInY,
|
||||
_dstGobBlocksInZ);
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
target.SetData(data, 0, 0, new GAL.Rectangle<int>(_dstX, _dstY, _lineLengthIn / target.Info.FormatInfo.BytesPerPixel, _lineCount));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var dstCalculator = new OffsetCalculator(
|
||||
_dstWidth,
|
||||
_dstHeight,
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
@ -151,10 +152,21 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
ulong ticks = _context.GetTimestamp();
|
||||
|
||||
float divisor = type switch
|
||||
{
|
||||
ReportCounterType.SamplesPassed => _channel.TextureManager.RenderTargetScale * _channel.TextureManager.RenderTargetScale,
|
||||
_ => 1f
|
||||
};
|
||||
|
||||
ICounterEvent counter = null;
|
||||
|
||||
void resultHandler(object evt, ulong result)
|
||||
{
|
||||
if (divisor != 1f)
|
||||
{
|
||||
result = (ulong)MathF.Ceiling(result / divisor);
|
||||
}
|
||||
|
||||
CounterData counterData = new CounterData
|
||||
{
|
||||
Counter = result,
|
||||
|
@ -8,195 +8,542 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// </summary>
|
||||
static class FormatTable
|
||||
{
|
||||
private static Dictionary<uint, FormatInfo> _textureFormats = new Dictionary<uint, FormatInfo>()
|
||||
private enum TextureFormat : uint
|
||||
{
|
||||
{ 0x2491d, new FormatInfo(Format.R8Unorm, 1, 1, 1, 1) },
|
||||
{ 0x1249d, new FormatInfo(Format.R8Snorm, 1, 1, 1, 1) },
|
||||
{ 0x4921d, new FormatInfo(Format.R8Uint, 1, 1, 1, 1) },
|
||||
{ 0x36d9d, new FormatInfo(Format.R8Sint, 1, 1, 1, 1) },
|
||||
{ 0x7ff9b, new FormatInfo(Format.R16Float, 1, 1, 2, 1) },
|
||||
{ 0x2491b, new FormatInfo(Format.R16Unorm, 1, 1, 2, 1) },
|
||||
{ 0x1249b, new FormatInfo(Format.R16Snorm, 1, 1, 2, 1) },
|
||||
{ 0x4921b, new FormatInfo(Format.R16Uint, 1, 1, 2, 1) },
|
||||
{ 0x36d9b, new FormatInfo(Format.R16Sint, 1, 1, 2, 1) },
|
||||
{ 0x7ff8f, new FormatInfo(Format.R32Float, 1, 1, 4, 1) },
|
||||
{ 0x4920f, new FormatInfo(Format.R32Uint, 1, 1, 4, 1) },
|
||||
{ 0x36d8f, new FormatInfo(Format.R32Sint, 1, 1, 4, 1) },
|
||||
{ 0x24918, new FormatInfo(Format.R8G8Unorm, 1, 1, 2, 2) },
|
||||
{ 0x12498, new FormatInfo(Format.R8G8Snorm, 1, 1, 2, 2) },
|
||||
{ 0x49218, new FormatInfo(Format.R8G8Uint, 1, 1, 2, 2) },
|
||||
{ 0x36d98, new FormatInfo(Format.R8G8Sint, 1, 1, 2, 2) },
|
||||
{ 0x7ff8c, new FormatInfo(Format.R16G16Float, 1, 1, 4, 2) },
|
||||
{ 0x2490c, new FormatInfo(Format.R16G16Unorm, 1, 1, 4, 2) },
|
||||
{ 0x1248c, new FormatInfo(Format.R16G16Snorm, 1, 1, 4, 2) },
|
||||
{ 0x4920c, new FormatInfo(Format.R16G16Uint, 1, 1, 4, 2) },
|
||||
{ 0x36d8c, new FormatInfo(Format.R16G16Sint, 1, 1, 4, 2) },
|
||||
{ 0x7ff84, new FormatInfo(Format.R32G32Float, 1, 1, 8, 2) },
|
||||
{ 0x49204, new FormatInfo(Format.R32G32Uint, 1, 1, 8, 2) },
|
||||
{ 0x36d84, new FormatInfo(Format.R32G32Sint, 1, 1, 8, 2) },
|
||||
{ 0x7ff82, new FormatInfo(Format.R32G32B32Float, 1, 1, 12, 3) },
|
||||
{ 0x49202, new FormatInfo(Format.R32G32B32Uint, 1, 1, 12, 3) },
|
||||
{ 0x36d82, new FormatInfo(Format.R32G32B32Sint, 1, 1, 12, 3) },
|
||||
{ 0x24908, new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4) },
|
||||
{ 0x12488, new FormatInfo(Format.R8G8B8A8Snorm, 1, 1, 4, 4) },
|
||||
{ 0x49208, new FormatInfo(Format.R8G8B8A8Uint, 1, 1, 4, 4) },
|
||||
{ 0x36d88, new FormatInfo(Format.R8G8B8A8Sint, 1, 1, 4, 4) },
|
||||
{ 0x7ff83, new FormatInfo(Format.R16G16B16A16Float, 1, 1, 8, 4) },
|
||||
{ 0x24903, new FormatInfo(Format.R16G16B16A16Unorm, 1, 1, 8, 4) },
|
||||
{ 0x12483, new FormatInfo(Format.R16G16B16A16Snorm, 1, 1, 8, 4) },
|
||||
{ 0x49203, new FormatInfo(Format.R16G16B16A16Uint, 1, 1, 8, 4) },
|
||||
{ 0x36d83, new FormatInfo(Format.R16G16B16A16Sint, 1, 1, 8, 4) },
|
||||
{ 0x7ff81, new FormatInfo(Format.R32G32B32A32Float, 1, 1, 16, 4) },
|
||||
{ 0x49201, new FormatInfo(Format.R32G32B32A32Uint, 1, 1, 16, 4) },
|
||||
{ 0x36d81, new FormatInfo(Format.R32G32B32A32Sint, 1, 1, 16, 4) },
|
||||
{ 0x2493a, new FormatInfo(Format.D16Unorm, 1, 1, 2, 1) },
|
||||
{ 0x493af, new FormatInfo(Format.D32Float, 1, 1, 4, 1) },
|
||||
{ 0x7ffaf, new FormatInfo(Format.D32Float, 1, 1, 4, 1) },
|
||||
{ 0x24a0e, new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4, 2) },
|
||||
{ 0x24a29, new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4, 2) },
|
||||
{ 0x48a29, new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4, 2) },
|
||||
{ 0x4912b, new FormatInfo(Format.S8UintD24Unorm, 1, 1, 4, 2) },
|
||||
{ 0x25385, new FormatInfo(Format.D32FloatS8Uint, 1, 1, 8, 2) },
|
||||
{ 0x253b0, new FormatInfo(Format.D32FloatS8Uint, 1, 1, 8, 2) },
|
||||
{ 0xa4908, new FormatInfo(Format.R8G8B8A8Srgb, 1, 1, 4, 4) },
|
||||
{ 0x2491e, new FormatInfo(Format.R4G4Unorm, 1, 1, 1, 2) },
|
||||
{ 0x24912, new FormatInfo(Format.R4G4B4A4Unorm, 1, 1, 2, 4) },
|
||||
{ 0x24914, new FormatInfo(Format.R5G5B5A1Unorm, 1, 1, 2, 4) },
|
||||
{ 0x24915, new FormatInfo(Format.R5G6B5Unorm, 1, 1, 2, 3) },
|
||||
{ 0x24909, new FormatInfo(Format.R10G10B10A2Unorm, 1, 1, 4, 4) },
|
||||
{ 0x49209, new FormatInfo(Format.R10G10B10A2Uint, 1, 1, 4, 4) },
|
||||
{ 0x7ffa1, new FormatInfo(Format.R11G11B10Float, 1, 1, 4, 3) },
|
||||
{ 0x7ffa0, new FormatInfo(Format.R9G9B9E5Float, 1, 1, 4, 4) },
|
||||
{ 0x24924, new FormatInfo(Format.Bc1RgbaUnorm, 4, 4, 8, 4) },
|
||||
{ 0x24925, new FormatInfo(Format.Bc2Unorm, 4, 4, 16, 4) },
|
||||
{ 0x24926, new FormatInfo(Format.Bc3Unorm, 4, 4, 16, 4) },
|
||||
{ 0xa4924, new FormatInfo(Format.Bc1RgbaSrgb, 4, 4, 8, 4) },
|
||||
{ 0xa4925, new FormatInfo(Format.Bc2Srgb, 4, 4, 16, 4) },
|
||||
{ 0xa4926, new FormatInfo(Format.Bc3Srgb, 4, 4, 16, 4) },
|
||||
{ 0x24927, new FormatInfo(Format.Bc4Unorm, 4, 4, 8, 1) },
|
||||
{ 0x124a7, new FormatInfo(Format.Bc4Snorm, 4, 4, 8, 1) },
|
||||
{ 0x24928, new FormatInfo(Format.Bc5Unorm, 4, 4, 16, 2) },
|
||||
{ 0x124a8, new FormatInfo(Format.Bc5Snorm, 4, 4, 16, 2) },
|
||||
{ 0x24917, new FormatInfo(Format.Bc7Unorm, 4, 4, 16, 4) },
|
||||
{ 0xa4917, new FormatInfo(Format.Bc7Srgb, 4, 4, 16, 4) },
|
||||
{ 0x7ff90, new FormatInfo(Format.Bc6HSfloat, 4, 4, 16, 4) },
|
||||
{ 0x7ff91, new FormatInfo(Format.Bc6HUfloat, 4, 4, 16, 4) },
|
||||
{ 0x24906, new FormatInfo(Format.Etc2RgbUnorm, 4, 4, 8, 3) },
|
||||
{ 0x2490b, new FormatInfo(Format.Etc2RgbaUnorm, 4, 4, 16, 4) },
|
||||
{ 0xa4906, new FormatInfo(Format.Etc2RgbSrgb, 4, 4, 8, 3) },
|
||||
{ 0xa490b, new FormatInfo(Format.Etc2RgbaSrgb, 4, 4, 16, 4) },
|
||||
{ 0x24940, new FormatInfo(Format.Astc4x4Unorm, 4, 4, 16, 4) },
|
||||
{ 0x24950, new FormatInfo(Format.Astc5x4Unorm, 5, 4, 16, 4) },
|
||||
{ 0x24941, new FormatInfo(Format.Astc5x5Unorm, 5, 5, 16, 4) },
|
||||
{ 0x24951, new FormatInfo(Format.Astc6x5Unorm, 6, 5, 16, 4) },
|
||||
{ 0x24942, new FormatInfo(Format.Astc6x6Unorm, 6, 6, 16, 4) },
|
||||
{ 0x24955, new FormatInfo(Format.Astc8x5Unorm, 8, 5, 16, 4) },
|
||||
{ 0x24952, new FormatInfo(Format.Astc8x6Unorm, 8, 6, 16, 4) },
|
||||
{ 0x24944, new FormatInfo(Format.Astc8x8Unorm, 8, 8, 16, 4) },
|
||||
{ 0x24956, new FormatInfo(Format.Astc10x5Unorm, 10, 5, 16, 4) },
|
||||
{ 0x24957, new FormatInfo(Format.Astc10x6Unorm, 10, 6, 16, 4) },
|
||||
{ 0x24953, new FormatInfo(Format.Astc10x8Unorm, 10, 8, 16, 4) },
|
||||
{ 0x24945, new FormatInfo(Format.Astc10x10Unorm, 10, 10, 16, 4) },
|
||||
{ 0x24954, new FormatInfo(Format.Astc12x10Unorm, 12, 10, 16, 4) },
|
||||
{ 0x24946, new FormatInfo(Format.Astc12x12Unorm, 12, 12, 16, 4) },
|
||||
{ 0xa4940, new FormatInfo(Format.Astc4x4Srgb, 4, 4, 16, 4) },
|
||||
{ 0xa4950, new FormatInfo(Format.Astc5x4Srgb, 5, 4, 16, 4) },
|
||||
{ 0xa4941, new FormatInfo(Format.Astc5x5Srgb, 5, 5, 16, 4) },
|
||||
{ 0xa4951, new FormatInfo(Format.Astc6x5Srgb, 6, 5, 16, 4) },
|
||||
{ 0xa4942, new FormatInfo(Format.Astc6x6Srgb, 6, 6, 16, 4) },
|
||||
{ 0xa4955, new FormatInfo(Format.Astc8x5Srgb, 8, 5, 16, 4) },
|
||||
{ 0xa4952, new FormatInfo(Format.Astc8x6Srgb, 8, 6, 16, 4) },
|
||||
{ 0xa4944, new FormatInfo(Format.Astc8x8Srgb, 8, 8, 16, 4) },
|
||||
{ 0xa4956, new FormatInfo(Format.Astc10x5Srgb, 10, 5, 16, 4) },
|
||||
{ 0xa4957, new FormatInfo(Format.Astc10x6Srgb, 10, 6, 16, 4) },
|
||||
{ 0xa4953, new FormatInfo(Format.Astc10x8Srgb, 10, 8, 16, 4) },
|
||||
{ 0xa4945, new FormatInfo(Format.Astc10x10Srgb, 10, 10, 16, 4) },
|
||||
{ 0xa4954, new FormatInfo(Format.Astc12x10Srgb, 12, 10, 16, 4) },
|
||||
{ 0xa4946, new FormatInfo(Format.Astc12x12Srgb, 12, 12, 16, 4) },
|
||||
{ 0x24913, new FormatInfo(Format.A1B5G5R5Unorm, 1, 1, 2, 4) }
|
||||
// Formats
|
||||
R32G32B32A32 = 0x01,
|
||||
R32G32B32 = 0x02,
|
||||
R16G16B16A16 = 0x03,
|
||||
R32G32 = 0x04,
|
||||
R32B24G8 = 0x05,
|
||||
X8B8G8R8 = 0x07,
|
||||
A8B8G8R8 = 0x08,
|
||||
A2B10G10R10 = 0x09,
|
||||
R16G16 = 0x0c,
|
||||
G8R24 = 0x0d,
|
||||
G24R8 = 0x0e,
|
||||
R32 = 0x0f,
|
||||
A4B4G4R4 = 0x12,
|
||||
A5B5G5R1 = 0x13,
|
||||
A1B5G5R5 = 0x14,
|
||||
B5G6R5 = 0x15,
|
||||
B6G5R5 = 0x16,
|
||||
G8R8 = 0x18,
|
||||
R16 = 0x1b,
|
||||
Y8Video = 0x1c,
|
||||
R8 = 0x1d,
|
||||
G4R4 = 0x1e,
|
||||
R1 = 0x1f,
|
||||
E5B9G9R9SharedExp = 0x20,
|
||||
Bf10Gf11Rf11 = 0x21,
|
||||
G8B8G8R8 = 0x22,
|
||||
B8G8R8G8 = 0x23,
|
||||
Bc1 = 0x24,
|
||||
Bc2 = 0x25,
|
||||
Bc3 = 0x26,
|
||||
Bc4 = 0x27,
|
||||
Bc5 = 0x28,
|
||||
Bc6HSf16 = 0x10,
|
||||
Bc6HUf16 = 0x11,
|
||||
Bc7U = 0x17,
|
||||
Etc2Rgb = 0x06,
|
||||
Etc2RgbPta = 0x0a,
|
||||
Etc2Rgba = 0x0b,
|
||||
Eac = 0x19,
|
||||
Eacx2 = 0x1a,
|
||||
Z24S8 = 0x29,
|
||||
X8Z24 = 0x2a,
|
||||
S8Z24 = 0x2b,
|
||||
X4V4Z24Cov4R4V = 0x2c,
|
||||
X4V4Z24Cov8R8V = 0x2d,
|
||||
V8Z24Cov4R12V = 0x2e,
|
||||
Zf32 = 0x2f,
|
||||
Zf32X24S8 = 0x30,
|
||||
X8Z24X20V4S8Cov4R4V = 0x31,
|
||||
X8Z24X20V4S8Cov8R8V = 0x32,
|
||||
Zf32X20V4X8Cov4R4V = 0x33,
|
||||
Zf32X20V4X8Cov8R8V = 0x34,
|
||||
Zf32X20V4S8Cov4R4V = 0x35,
|
||||
Zf32X20V4S8Cov8R8V = 0x36,
|
||||
X8Z24X16V8S8Cov4R12V = 0x37,
|
||||
Zf32X16V8X8Cov4R12V = 0x38,
|
||||
Zf32X16V8S8Cov4R12V = 0x39,
|
||||
Z16 = 0x3a,
|
||||
V8Z24Cov8R24V = 0x3b,
|
||||
X8Z24X16V8S8Cov8R24V = 0x3c,
|
||||
Zf32X16V8X8Cov8R24V = 0x3d,
|
||||
Zf32X16V8S8Cov8R24V = 0x3e,
|
||||
Astc2D4x4 = 0x40,
|
||||
Astc2D5x4 = 0x50,
|
||||
Astc2D5x5 = 0x41,
|
||||
Astc2D6x5 = 0x51,
|
||||
Astc2D6x6 = 0x42,
|
||||
Astc2D8x5 = 0x55,
|
||||
Astc2D8x6 = 0x52,
|
||||
Astc2D8x8 = 0x44,
|
||||
Astc2D10x5 = 0x56,
|
||||
Astc2D10x6 = 0x57,
|
||||
Astc2D10x8 = 0x53,
|
||||
Astc2D10x10 = 0x45,
|
||||
Astc2D12x10 = 0x54,
|
||||
Astc2D12x12 = 0x46,
|
||||
|
||||
// Types
|
||||
Snorm = 0x1,
|
||||
Unorm = 0x2,
|
||||
Sint = 0x3,
|
||||
Uint = 0x4,
|
||||
SnormForceFp16 = 0x5,
|
||||
UnormForceFp16 = 0x6,
|
||||
Float = 0x7,
|
||||
|
||||
// Component Types
|
||||
RSnorm = Snorm << 7,
|
||||
GSnorm = Snorm << 10,
|
||||
BSnorm = Snorm << 13,
|
||||
ASnorm = Snorm << 16,
|
||||
|
||||
RUnorm = Unorm << 7,
|
||||
GUnorm = Unorm << 10,
|
||||
BUnorm = Unorm << 13,
|
||||
AUnorm = Unorm << 16,
|
||||
|
||||
RSint = Sint << 7,
|
||||
GSint = Sint << 10,
|
||||
BSint = Sint << 13,
|
||||
ASint = Sint << 16,
|
||||
|
||||
RUint = Uint << 7,
|
||||
GUint = Uint << 10,
|
||||
BUint = Uint << 13,
|
||||
AUint = Uint << 16,
|
||||
|
||||
RSnormForceFp16 = SnormForceFp16 << 7,
|
||||
GSnormForceFp16 = SnormForceFp16 << 10,
|
||||
BSnormForceFp16 = SnormForceFp16 << 13,
|
||||
ASnormForceFp16 = SnormForceFp16 << 16,
|
||||
|
||||
RUnormForceFp16 = UnormForceFp16 << 7,
|
||||
GUnormForceFp16 = UnormForceFp16 << 10,
|
||||
BUnormForceFp16 = UnormForceFp16 << 13,
|
||||
AUnormForceFp16 = UnormForceFp16 << 16,
|
||||
|
||||
RFloat = Float << 7,
|
||||
GFloat = Float << 10,
|
||||
BFloat = Float << 13,
|
||||
AFloat = Float << 16,
|
||||
|
||||
Srgb = 0x1 << 19, // Custom encoding
|
||||
|
||||
// Combinations
|
||||
R8Unorm = R8 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x2491d
|
||||
R8Snorm = R8 | RSnorm | GSnorm | BSnorm | ASnorm, // 0x1249d
|
||||
R8Uint = R8 | RUint | GUint | BUint | AUint, // 0x4921d
|
||||
R8Sint = R8 | RSint | GSint | BSint | ASint, // 0x36d9d
|
||||
R16Float = R16 | RFloat | GFloat | BFloat | AFloat, // 0x7ff9b
|
||||
R16Unorm = R16 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x2491b
|
||||
R16Snorm = R16 | RSnorm | GSnorm | BSnorm | ASnorm, // 0x1249b
|
||||
R16Uint = R16 | RUint | GUint | BUint | AUint, // 0x4921b
|
||||
R16Sint = R16 | RSint | GSint | BSint | ASint, // 0x36d9b
|
||||
R32Float = R32 | RFloat | GFloat | BFloat | AFloat, // 0x7ff8f
|
||||
R32Uint = R32 | RUint | GUint | BUint | AUint, // 0x4920f
|
||||
R32Sint = R32 | RSint | GSint | BSint | ASint, // 0x36d8f
|
||||
G8R8Unorm = G8R8 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24918
|
||||
G8R8Snorm = G8R8 | RSnorm | GSnorm | BSnorm | ASnorm, // 0x12498
|
||||
G8R8Uint = G8R8 | RUint | GUint | BUint | AUint, // 0x49218
|
||||
G8R8Sint = G8R8 | RSint | GSint | BSint | ASint, // 0x36d98
|
||||
R16G16Float = R16G16 | RFloat | GFloat | BFloat | AFloat, // 0x7ff8c
|
||||
R16G16Unorm = R16G16 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x2490c
|
||||
R16G16Snorm = R16G16 | RSnorm | GSnorm | BSnorm | ASnorm, // 0x1248c
|
||||
R16G16Uint = R16G16 | RUint | GUint | BUint | AUint, // 0x4920c
|
||||
R16G16Sint = R16G16 | RSint | GSint | BSint | ASint, // 0x36d8c
|
||||
R32G32Float = R32G32 | RFloat | GFloat | BFloat | AFloat, // 0x7ff84
|
||||
R32G32Uint = R32G32 | RUint | GUint | BUint | AUint, // 0x49204
|
||||
R32G32Sint = R32G32 | RSint | GSint | BSint | ASint, // 0x36d84
|
||||
R32G32B32Float = R32G32B32 | RFloat | GFloat | BFloat | AFloat, // 0x7ff82
|
||||
R32G32B32Uint = R32G32B32 | RUint | GUint | BUint | AUint, // 0x49202
|
||||
R32G32B32Sint = R32G32B32 | RSint | GSint | BSint | ASint, // 0x36d82
|
||||
A8B8G8R8Unorm = A8B8G8R8 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24908
|
||||
A8B8G8R8Snorm = A8B8G8R8 | RSnorm | GSnorm | BSnorm | ASnorm, // 0x12488
|
||||
A8B8G8R8Uint = A8B8G8R8 | RUint | GUint | BUint | AUint, // 0x49208
|
||||
A8B8G8R8Sint = A8B8G8R8 | RSint | GSint | BSint | ASint, // 0x36d88
|
||||
R16G16B16A16Float = R16G16B16A16 | RFloat | GFloat | BFloat | AFloat, // 0x7ff83
|
||||
R16G16B16A16Unorm = R16G16B16A16 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24903
|
||||
R16G16B16A16Snorm = R16G16B16A16 | RSnorm | GSnorm | BSnorm | ASnorm, // 0x12483
|
||||
R16G16B16A16Uint = R16G16B16A16 | RUint | GUint | BUint | AUint, // 0x49203
|
||||
R16G16B16A16Sint = R16G16B16A16 | RSint | GSint | BSint | ASint, // 0x36d83
|
||||
R32G32B32A32Float = R32G32B32A32 | RFloat | GFloat | BFloat | AFloat, // 0x7ff81
|
||||
R32G32B32A32Uint = R32G32B32A32 | RUint | GUint | BUint | AUint, // 0x49201
|
||||
R32G32B32A32Sint = R32G32B32A32 | RSint | GSint | BSint | ASint, // 0x36d81
|
||||
Z16Unorm = Z16 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x2493a
|
||||
Zf32RFloatGUintBUintAUint = Zf32 | RFloat | GUint | BUint | AUint, // 0x493af
|
||||
Zf32Float = Zf32 | RFloat | GFloat | BFloat | AFloat, // 0x7ffaf
|
||||
G24R8RUintGUnormBUnormAUnorm = G24R8 | RUint | GUnorm | BUnorm | AUnorm, // 0x24a0e
|
||||
Z24S8RUintGUnormBUnormAUnorm = Z24S8 | RUint | GUnorm | BUnorm | AUnorm, // 0x24a29
|
||||
Z24S8RUintGUnormBUintAUint = Z24S8 | RUint | GUnorm | BUint | AUint, // 0x48a29
|
||||
S8Z24RUnormGUintBUintAUint = S8Z24 | RUnorm | GUint | BUint | AUint, // 0x4912b
|
||||
R32B24G8RFloatGUintBUnormAUnorm = R32B24G8 | RFloat | GUint | BUnorm | AUnorm, // 0x25385
|
||||
Zf32X24S8RFloatGUintBUnormAUnorm = Zf32X24S8 | RFloat | GUint | BUnorm | AUnorm, // 0x253b0
|
||||
A8B8G8R8UnormSrgb = A8B8G8R8 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4908
|
||||
G4R4Unorm = G4R4 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x2491e
|
||||
A4B4G4R4Unorm = A4B4G4R4 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24912
|
||||
A1B5G5R5Unorm = A1B5G5R5 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24914
|
||||
B5G6R5Unorm = B5G6R5 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24915
|
||||
A2B10G10R10Unorm = A2B10G10R10 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24909
|
||||
A2B10G10R10Uint = A2B10G10R10 | RUint | GUint | BUint | AUint, // 0x49209
|
||||
Bf10Gf11Rf11Float = Bf10Gf11Rf11 | RFloat | GFloat | BFloat | AFloat, // 0x7ffa1
|
||||
E5B9G9R9SharedExpFloat = E5B9G9R9SharedExp | RFloat | GFloat | BFloat | AFloat, // 0x7ffa0
|
||||
Bc1Unorm = Bc1 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24924
|
||||
Bc2Unorm = Bc2 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24925
|
||||
Bc3Unorm = Bc3 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24926
|
||||
Bc1UnormSrgb = Bc1 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4924
|
||||
Bc2UnormSrgb = Bc2 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4925
|
||||
Bc3UnormSrgb = Bc3 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4926
|
||||
Bc4Unorm = Bc4 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24927
|
||||
Bc4Snorm = Bc4 | RSnorm | GSnorm | BSnorm | ASnorm, // 0x124a7
|
||||
Bc5Unorm = Bc5 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24928
|
||||
Bc5Snorm = Bc5 | RSnorm | GSnorm | BSnorm | ASnorm, // 0x124a8
|
||||
Bc7UUnorm = Bc7U | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24917
|
||||
Bc7UUnormSrgb = Bc7U | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4917
|
||||
Bc6HSf16Float = Bc6HSf16 | RFloat | GFloat | BFloat | AFloat, // 0x7ff90
|
||||
Bc6HUf16Float = Bc6HUf16 | RFloat | GFloat | BFloat | AFloat, // 0x7ff91
|
||||
Etc2RgbUnorm = Etc2Rgb | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24906
|
||||
Etc2RgbaUnorm = Etc2Rgba | RUnorm | GUnorm | BUnorm | AUnorm, // 0x2490b
|
||||
Etc2RgbUnormSrgb = Etc2Rgb | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4906
|
||||
Etc2RgbaUnormSrgb = Etc2Rgba | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa490b
|
||||
Astc2D4x4Unorm = Astc2D4x4 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24940
|
||||
Astc2D5x4Unorm = Astc2D5x4 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24950
|
||||
Astc2D5x5Unorm = Astc2D5x5 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24941
|
||||
Astc2D6x5Unorm = Astc2D6x5 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24951
|
||||
Astc2D6x6Unorm = Astc2D6x6 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24942
|
||||
Astc2D8x5Unorm = Astc2D8x5 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24955
|
||||
Astc2D8x6Unorm = Astc2D8x6 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24952
|
||||
Astc2D8x8Unorm = Astc2D8x8 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24944
|
||||
Astc2D10x5Unorm = Astc2D10x5 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24956
|
||||
Astc2D10x6Unorm = Astc2D10x6 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24957
|
||||
Astc2D10x8Unorm = Astc2D10x8 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24953
|
||||
Astc2D10x10Unorm = Astc2D10x10 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24945
|
||||
Astc2D12x10Unorm = Astc2D12x10 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24954
|
||||
Astc2D12x12Unorm = Astc2D12x12 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24946
|
||||
Astc2D4x4UnormSrgb = Astc2D4x4 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4940
|
||||
Astc2D5x4UnormSrgb = Astc2D5x4 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4950
|
||||
Astc2D5x5UnormSrgb = Astc2D5x5 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4941
|
||||
Astc2D6x5UnormSrgb = Astc2D6x5 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4951
|
||||
Astc2D6x6UnormSrgb = Astc2D6x6 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4942
|
||||
Astc2D8x5UnormSrgb = Astc2D8x5 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4955
|
||||
Astc2D8x6UnormSrgb = Astc2D8x6 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4952
|
||||
Astc2D8x8UnormSrgb = Astc2D8x8 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4944
|
||||
Astc2D10x5UnormSrgb = Astc2D10x5 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4956
|
||||
Astc2D10x6UnormSrgb = Astc2D10x6 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4957
|
||||
Astc2D10x8UnormSrgb = Astc2D10x8 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4953
|
||||
Astc2D10x10UnormSrgb = Astc2D10x10 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4945
|
||||
Astc2D12x10UnormSrgb = Astc2D12x10 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4954
|
||||
Astc2D12x12UnormSrgb = Astc2D12x12 | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4946
|
||||
A5B5G5R1Unorm = A5B5G5R1 | RUnorm | GUnorm | BUnorm | AUnorm, // 0x24913
|
||||
}
|
||||
|
||||
private enum VertexAttributeFormat : uint
|
||||
{
|
||||
// Width
|
||||
R32G32B32A32 = 0x01,
|
||||
R32G32B32 = 0x02,
|
||||
R16G16B16A16 = 0x03,
|
||||
R32G32 = 0x04,
|
||||
R16G16B16 = 0x05,
|
||||
A8B8G8R8 = 0x2f,
|
||||
R8G8B8A8 = 0x0a,
|
||||
X8B8G8R8 = 0x33,
|
||||
A2B10G10R10 = 0x30,
|
||||
B10G11R11 = 0x31,
|
||||
R16G16 = 0x0f,
|
||||
R32 = 0x12,
|
||||
R8G8B8 = 0x13,
|
||||
G8R8 = 0x32,
|
||||
R8G8 = 0x18,
|
||||
R16 = 0x1b,
|
||||
R8 = 0x1d,
|
||||
A8 = 0x34,
|
||||
|
||||
// Type
|
||||
Snorm = 0x01,
|
||||
Unorm = 0x02,
|
||||
Sint = 0x03,
|
||||
Uint = 0x04,
|
||||
Uscaled = 0x05,
|
||||
Sscaled = 0x06,
|
||||
Float = 0x07,
|
||||
|
||||
// Combinations
|
||||
R8Unorm = (R8 << 21) | (Unorm << 27), // 0x13a00000
|
||||
R8Snorm = (R8 << 21) | (Snorm << 27), // 0x0ba00000
|
||||
R8Uint = (R8 << 21) | (Uint << 27), // 0x23a00000
|
||||
R8Sint = (R8 << 21) | (Sint << 27), // 0x1ba00000
|
||||
R16Float = (R16 << 21) | (Float << 27), // 0x3b600000
|
||||
R16Unorm = (R16 << 21) | (Unorm << 27), // 0x13600000
|
||||
R16Snorm = (R16 << 21) | (Snorm << 27), // 0x0b600000
|
||||
R16Uint = (R16 << 21) | (Uint << 27), // 0x23600000
|
||||
R16Sint = (R16 << 21) | (Sint << 27), // 0x1b600000
|
||||
R32Float = (R32 << 21) | (Float << 27), // 0x3a400000
|
||||
R32Uint = (R32 << 21) | (Uint << 27), // 0x22400000
|
||||
R32Sint = (R32 << 21) | (Sint << 27), // 0x1a400000
|
||||
R8G8Unorm = (R8G8 << 21) | (Unorm << 27), // 0x13000000
|
||||
R8G8Snorm = (R8G8 << 21) | (Snorm << 27), // 0x0b000000
|
||||
R8G8Uint = (R8G8 << 21) | (Uint << 27), // 0x23000000
|
||||
R8G8Sint = (R8G8 << 21) | (Sint << 27), // 0x1b000000
|
||||
R16G16Float = (R16G16 << 21) | (Float << 27), // 0x39e00000
|
||||
R16G16Unorm = (R16G16 << 21) | (Unorm << 27), // 0x11e00000
|
||||
R16G16Snorm = (R16G16 << 21) | (Snorm << 27), // 0x09e00000
|
||||
R16G16Uint = (R16G16 << 21) | (Uint << 27), // 0x21e00000
|
||||
R16G16Sint = (R16G16 << 21) | (Sint << 27), // 0x19e00000
|
||||
R32G32Float = (R32G32 << 21) | (Float << 27), // 0x38800000
|
||||
R32G32Uint = (R32G32 << 21) | (Uint << 27), // 0x20800000
|
||||
R32G32Sint = (R32G32 << 21) | (Sint << 27), // 0x18800000
|
||||
R8G8B8Unorm = (R8G8B8 << 21) | (Unorm << 27), // 0x12600000
|
||||
R8G8B8Snorm = (R8G8B8 << 21) | (Snorm << 27), // 0x0a600000
|
||||
R8G8B8Uint = (R8G8B8 << 21) | (Uint << 27), // 0x22600000
|
||||
R8G8B8Sint = (R8G8B8 << 21) | (Sint << 27), // 0x1a600000
|
||||
R16G16B16Float = (R16G16B16 << 21) | (Float << 27), // 0x38a00000
|
||||
R16G16B16Unorm = (R16G16B16 << 21) | (Unorm << 27), // 0x10a00000
|
||||
R16G16B16Snorm = (R16G16B16 << 21) | (Snorm << 27), // 0x08a00000
|
||||
R16G16B16Uint = (R16G16B16 << 21) | (Uint << 27), // 0x20a00000
|
||||
R16G16B16Sint = (R16G16B16 << 21) | (Sint << 27), // 0x18a00000
|
||||
R32G32B32Float = (R32G32B32 << 21) | (Float << 27), // 0x38400000
|
||||
R32G32B32Uint = (R32G32B32 << 21) | (Uint << 27), // 0x20400000
|
||||
R32G32B32Sint = (R32G32B32 << 21) | (Sint << 27), // 0x18400000
|
||||
R8G8B8A8Unorm = (R8G8B8A8 << 21) | (Unorm << 27), // 0x11400000
|
||||
R8G8B8A8Snorm = (R8G8B8A8 << 21) | (Snorm << 27), // 0x09400000
|
||||
R8G8B8A8Uint = (R8G8B8A8 << 21) | (Uint << 27), // 0x21400000
|
||||
R8G8B8A8Sint = (R8G8B8A8 << 21) | (Sint << 27), // 0x19400000
|
||||
R16G16B16A16Float = (R16G16B16A16 << 21) | (Float << 27), // 0x38600000
|
||||
R16G16B16A16Unorm = (R16G16B16A16 << 21) | (Unorm << 27), // 0x10600000
|
||||
R16G16B16A16Snorm = (R16G16B16A16 << 21) | (Snorm << 27), // 0x08600000
|
||||
R16G16B16A16Uint = (R16G16B16A16 << 21) | (Uint << 27), // 0x20600000
|
||||
R16G16B16A16Sint = (R16G16B16A16 << 21) | (Sint << 27), // 0x18600000
|
||||
R32G32B32A32Float = (R32G32B32A32 << 21) | (Float << 27), // 0x38200000
|
||||
R32G32B32A32Uint = (R32G32B32A32 << 21) | (Uint << 27), // 0x20200000
|
||||
R32G32B32A32Sint = (R32G32B32A32 << 21) | (Sint << 27), // 0x18200000
|
||||
A2B10G10R10Unorm = (A2B10G10R10 << 21) | (Unorm << 27), // 0x16000000
|
||||
A2B10G10R10Uint = (A2B10G10R10 << 21) | (Uint << 27), // 0x26000000
|
||||
B10G11R11Float = (B10G11R11 << 21) | (Float << 27), // 0x3e200000
|
||||
R8Uscaled = (R8 << 21) | (Uscaled << 27), // 0x2ba00000
|
||||
R8Sscaled = (R8 << 21) | (Sscaled << 27), // 0x33a00000
|
||||
R16Uscaled = (R16 << 21) | (Uscaled << 27), // 0x2b600000
|
||||
R16Sscaled = (R16 << 21) | (Sscaled << 27), // 0x33600000
|
||||
R32Uscaled = (R32 << 21) | (Uscaled << 27), // 0x2a400000
|
||||
R32Sscaled = (R32 << 21) | (Sscaled << 27), // 0x32400000
|
||||
R8G8Uscaled = (R8G8 << 21) | (Uscaled << 27), // 0x2b000000
|
||||
R8G8Sscaled = (R8G8 << 21) | (Sscaled << 27), // 0x33000000
|
||||
R16G16Uscaled = (R16G16 << 21) | (Uscaled << 27), // 0x29e00000
|
||||
R16G16Sscaled = (R16G16 << 21) | (Sscaled << 27), // 0x31e00000
|
||||
R32G32Uscaled = (R32G32 << 21) | (Uscaled << 27), // 0x28800000
|
||||
R32G32Sscaled = (R32G32 << 21) | (Sscaled << 27), // 0x30800000
|
||||
R8G8B8Uscaled = (R8G8B8 << 21) | (Uscaled << 27), // 0x2a600000
|
||||
R8G8B8Sscaled = (R8G8B8 << 21) | (Sscaled << 27), // 0x32600000
|
||||
R16G16B16Uscaled = (R16G16B16 << 21) | (Uscaled << 27), // 0x28a00000
|
||||
R16G16B16Sscaled = (R16G16B16 << 21) | (Sscaled << 27), // 0x30a00000
|
||||
R32G32B32Uscaled = (R32G32B32 << 21) | (Uscaled << 27), // 0x28400000
|
||||
R32G32B32Sscaled = (R32G32B32 << 21) | (Sscaled << 27), // 0x30400000
|
||||
R8G8B8A8Uscaled = (R8G8B8A8 << 21) | (Uscaled << 27), // 0x29400000
|
||||
R8G8B8A8Sscaled = (R8G8B8A8 << 21) | (Sscaled << 27), // 0x31400000
|
||||
R16G16B16A16Uscaled = (R16G16B16A16 << 21) | (Uscaled << 27), // 0x28600000
|
||||
R16G16B16A16Sscaled = (R16G16B16A16 << 21) | (Sscaled << 27), // 0x30600000
|
||||
R32G32B32A32Uscaled = (R32G32B32A32 << 21) | (Uscaled << 27), // 0x28200000
|
||||
R32G32B32A32Sscaled = (R32G32B32A32 << 21) | (Sscaled << 27), // 0x30200000
|
||||
A2B10G10R10Snorm = (A2B10G10R10 << 21) | (Snorm << 27), // 0x0e000000
|
||||
A2B10G10R10Sint = (A2B10G10R10 << 21) | (Sint << 27), // 0x1e000000
|
||||
A2B10G10R10Uscaled = (A2B10G10R10 << 21) | (Uscaled << 27), // 0x2e000000
|
||||
A2B10G10R10Sscaled = (A2B10G10R10 << 21) | (Sscaled << 27), // 0x36000000
|
||||
}
|
||||
|
||||
private static readonly Dictionary<TextureFormat, FormatInfo> _textureFormats = new Dictionary<TextureFormat, FormatInfo>()
|
||||
{
|
||||
{ TextureFormat.R8Unorm, new FormatInfo(Format.R8Unorm, 1, 1, 1, 1) },
|
||||
{ TextureFormat.R8Snorm, new FormatInfo(Format.R8Snorm, 1, 1, 1, 1) },
|
||||
{ TextureFormat.R8Uint, new FormatInfo(Format.R8Uint, 1, 1, 1, 1) },
|
||||
{ TextureFormat.R8Sint, new FormatInfo(Format.R8Sint, 1, 1, 1, 1) },
|
||||
{ TextureFormat.R16Float, new FormatInfo(Format.R16Float, 1, 1, 2, 1) },
|
||||
{ TextureFormat.R16Unorm, new FormatInfo(Format.R16Unorm, 1, 1, 2, 1) },
|
||||
{ TextureFormat.R16Snorm, new FormatInfo(Format.R16Snorm, 1, 1, 2, 1) },
|
||||
{ TextureFormat.R16Uint, new FormatInfo(Format.R16Uint, 1, 1, 2, 1) },
|
||||
{ TextureFormat.R16Sint, new FormatInfo(Format.R16Sint, 1, 1, 2, 1) },
|
||||
{ TextureFormat.R32Float, new FormatInfo(Format.R32Float, 1, 1, 4, 1) },
|
||||
{ TextureFormat.R32Uint, new FormatInfo(Format.R32Uint, 1, 1, 4, 1) },
|
||||
{ TextureFormat.R32Sint, new FormatInfo(Format.R32Sint, 1, 1, 4, 1) },
|
||||
{ TextureFormat.G8R8Unorm, new FormatInfo(Format.R8G8Unorm, 1, 1, 2, 2) },
|
||||
{ TextureFormat.G8R8Snorm, new FormatInfo(Format.R8G8Snorm, 1, 1, 2, 2) },
|
||||
{ TextureFormat.G8R8Uint, new FormatInfo(Format.R8G8Uint, 1, 1, 2, 2) },
|
||||
{ TextureFormat.G8R8Sint, new FormatInfo(Format.R8G8Sint, 1, 1, 2, 2) },
|
||||
{ TextureFormat.R16G16Float, new FormatInfo(Format.R16G16Float, 1, 1, 4, 2) },
|
||||
{ TextureFormat.R16G16Unorm, new FormatInfo(Format.R16G16Unorm, 1, 1, 4, 2) },
|
||||
{ TextureFormat.R16G16Snorm, new FormatInfo(Format.R16G16Snorm, 1, 1, 4, 2) },
|
||||
{ TextureFormat.R16G16Uint, new FormatInfo(Format.R16G16Uint, 1, 1, 4, 2) },
|
||||
{ TextureFormat.R16G16Sint, new FormatInfo(Format.R16G16Sint, 1, 1, 4, 2) },
|
||||
{ TextureFormat.R32G32Float, new FormatInfo(Format.R32G32Float, 1, 1, 8, 2) },
|
||||
{ TextureFormat.R32G32Uint, new FormatInfo(Format.R32G32Uint, 1, 1, 8, 2) },
|
||||
{ TextureFormat.R32G32Sint, new FormatInfo(Format.R32G32Sint, 1, 1, 8, 2) },
|
||||
{ TextureFormat.R32G32B32Float, new FormatInfo(Format.R32G32B32Float, 1, 1, 12, 3) },
|
||||
{ TextureFormat.R32G32B32Uint, new FormatInfo(Format.R32G32B32Uint, 1, 1, 12, 3) },
|
||||
{ TextureFormat.R32G32B32Sint, new FormatInfo(Format.R32G32B32Sint, 1, 1, 12, 3) },
|
||||
{ TextureFormat.A8B8G8R8Unorm, new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4) },
|
||||
{ TextureFormat.A8B8G8R8Snorm, new FormatInfo(Format.R8G8B8A8Snorm, 1, 1, 4, 4) },
|
||||
{ TextureFormat.A8B8G8R8Uint, new FormatInfo(Format.R8G8B8A8Uint, 1, 1, 4, 4) },
|
||||
{ TextureFormat.A8B8G8R8Sint, new FormatInfo(Format.R8G8B8A8Sint, 1, 1, 4, 4) },
|
||||
{ TextureFormat.R16G16B16A16Float, new FormatInfo(Format.R16G16B16A16Float, 1, 1, 8, 4) },
|
||||
{ TextureFormat.R16G16B16A16Unorm, new FormatInfo(Format.R16G16B16A16Unorm, 1, 1, 8, 4) },
|
||||
{ TextureFormat.R16G16B16A16Snorm, new FormatInfo(Format.R16G16B16A16Snorm, 1, 1, 8, 4) },
|
||||
{ TextureFormat.R16G16B16A16Uint, new FormatInfo(Format.R16G16B16A16Uint, 1, 1, 8, 4) },
|
||||
{ TextureFormat.R16G16B16A16Sint, new FormatInfo(Format.R16G16B16A16Sint, 1, 1, 8, 4) },
|
||||
{ TextureFormat.R32G32B32A32Float, new FormatInfo(Format.R32G32B32A32Float, 1, 1, 16, 4) },
|
||||
{ TextureFormat.R32G32B32A32Uint, new FormatInfo(Format.R32G32B32A32Uint, 1, 1, 16, 4) },
|
||||
{ TextureFormat.R32G32B32A32Sint, new FormatInfo(Format.R32G32B32A32Sint, 1, 1, 16, 4) },
|
||||
{ TextureFormat.Z16Unorm, new FormatInfo(Format.D16Unorm, 1, 1, 2, 1) },
|
||||
{ TextureFormat.Zf32RFloatGUintBUintAUint, new FormatInfo(Format.D32Float, 1, 1, 4, 1) },
|
||||
{ TextureFormat.Zf32Float, new FormatInfo(Format.D32Float, 1, 1, 4, 1) },
|
||||
{ TextureFormat.G24R8RUintGUnormBUnormAUnorm, new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4, 2) },
|
||||
{ TextureFormat.Z24S8RUintGUnormBUnormAUnorm, new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4, 2) },
|
||||
{ TextureFormat.Z24S8RUintGUnormBUintAUint, new FormatInfo(Format.D24UnormS8Uint, 1, 1, 4, 2) },
|
||||
{ TextureFormat.S8Z24RUnormGUintBUintAUint, new FormatInfo(Format.S8UintD24Unorm, 1, 1, 4, 2) },
|
||||
{ TextureFormat.R32B24G8RFloatGUintBUnormAUnorm, new FormatInfo(Format.D32FloatS8Uint, 1, 1, 8, 2) },
|
||||
{ TextureFormat.Zf32X24S8RFloatGUintBUnormAUnorm, new FormatInfo(Format.D32FloatS8Uint, 1, 1, 8, 2) },
|
||||
{ TextureFormat.A8B8G8R8UnormSrgb, new FormatInfo(Format.R8G8B8A8Srgb, 1, 1, 4, 4) },
|
||||
{ TextureFormat.G4R4Unorm, new FormatInfo(Format.R4G4Unorm, 1, 1, 1, 2) },
|
||||
{ TextureFormat.A4B4G4R4Unorm, new FormatInfo(Format.R4G4B4A4Unorm, 1, 1, 2, 4) },
|
||||
{ TextureFormat.A1B5G5R5Unorm, new FormatInfo(Format.R5G5B5A1Unorm, 1, 1, 2, 4) },
|
||||
{ TextureFormat.B5G6R5Unorm, new FormatInfo(Format.R5G6B5Unorm, 1, 1, 2, 3) },
|
||||
{ TextureFormat.A2B10G10R10Unorm, new FormatInfo(Format.R10G10B10A2Unorm, 1, 1, 4, 4) },
|
||||
{ TextureFormat.A2B10G10R10Uint, new FormatInfo(Format.R10G10B10A2Uint, 1, 1, 4, 4) },
|
||||
{ TextureFormat.Bf10Gf11Rf11Float, new FormatInfo(Format.R11G11B10Float, 1, 1, 4, 3) },
|
||||
{ TextureFormat.E5B9G9R9SharedExpFloat, new FormatInfo(Format.R9G9B9E5Float, 1, 1, 4, 4) },
|
||||
{ TextureFormat.Bc1Unorm, new FormatInfo(Format.Bc1RgbaUnorm, 4, 4, 8, 4) },
|
||||
{ TextureFormat.Bc2Unorm, new FormatInfo(Format.Bc2Unorm, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Bc3Unorm, new FormatInfo(Format.Bc3Unorm, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Bc1UnormSrgb, new FormatInfo(Format.Bc1RgbaSrgb, 4, 4, 8, 4) },
|
||||
{ TextureFormat.Bc2UnormSrgb, new FormatInfo(Format.Bc2Srgb, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Bc3UnormSrgb, new FormatInfo(Format.Bc3Srgb, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Bc4Unorm, new FormatInfo(Format.Bc4Unorm, 4, 4, 8, 1) },
|
||||
{ TextureFormat.Bc4Snorm, new FormatInfo(Format.Bc4Snorm, 4, 4, 8, 1) },
|
||||
{ TextureFormat.Bc5Unorm, new FormatInfo(Format.Bc5Unorm, 4, 4, 16, 2) },
|
||||
{ TextureFormat.Bc5Snorm, new FormatInfo(Format.Bc5Snorm, 4, 4, 16, 2) },
|
||||
{ TextureFormat.Bc7UUnorm, new FormatInfo(Format.Bc7Unorm, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Bc7UUnormSrgb, new FormatInfo(Format.Bc7Srgb, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Bc6HSf16Float, new FormatInfo(Format.Bc6HSfloat, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Bc6HUf16Float, new FormatInfo(Format.Bc6HUfloat, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Etc2RgbUnorm, new FormatInfo(Format.Etc2RgbUnorm, 4, 4, 8, 3) },
|
||||
{ TextureFormat.Etc2RgbaUnorm, new FormatInfo(Format.Etc2RgbaUnorm, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Etc2RgbUnormSrgb, new FormatInfo(Format.Etc2RgbSrgb, 4, 4, 8, 3) },
|
||||
{ TextureFormat.Etc2RgbaUnormSrgb, new FormatInfo(Format.Etc2RgbaSrgb, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Astc2D4x4Unorm, new FormatInfo(Format.Astc4x4Unorm, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Astc2D5x4Unorm, new FormatInfo(Format.Astc5x4Unorm, 5, 4, 16, 4) },
|
||||
{ TextureFormat.Astc2D5x5Unorm, new FormatInfo(Format.Astc5x5Unorm, 5, 5, 16, 4) },
|
||||
{ TextureFormat.Astc2D6x5Unorm, new FormatInfo(Format.Astc6x5Unorm, 6, 5, 16, 4) },
|
||||
{ TextureFormat.Astc2D6x6Unorm, new FormatInfo(Format.Astc6x6Unorm, 6, 6, 16, 4) },
|
||||
{ TextureFormat.Astc2D8x5Unorm, new FormatInfo(Format.Astc8x5Unorm, 8, 5, 16, 4) },
|
||||
{ TextureFormat.Astc2D8x6Unorm, new FormatInfo(Format.Astc8x6Unorm, 8, 6, 16, 4) },
|
||||
{ TextureFormat.Astc2D8x8Unorm, new FormatInfo(Format.Astc8x8Unorm, 8, 8, 16, 4) },
|
||||
{ TextureFormat.Astc2D10x5Unorm, new FormatInfo(Format.Astc10x5Unorm, 10, 5, 16, 4) },
|
||||
{ TextureFormat.Astc2D10x6Unorm, new FormatInfo(Format.Astc10x6Unorm, 10, 6, 16, 4) },
|
||||
{ TextureFormat.Astc2D10x8Unorm, new FormatInfo(Format.Astc10x8Unorm, 10, 8, 16, 4) },
|
||||
{ TextureFormat.Astc2D10x10Unorm, new FormatInfo(Format.Astc10x10Unorm, 10, 10, 16, 4) },
|
||||
{ TextureFormat.Astc2D12x10Unorm, new FormatInfo(Format.Astc12x10Unorm, 12, 10, 16, 4) },
|
||||
{ TextureFormat.Astc2D12x12Unorm, new FormatInfo(Format.Astc12x12Unorm, 12, 12, 16, 4) },
|
||||
{ TextureFormat.Astc2D4x4UnormSrgb, new FormatInfo(Format.Astc4x4Srgb, 4, 4, 16, 4) },
|
||||
{ TextureFormat.Astc2D5x4UnormSrgb, new FormatInfo(Format.Astc5x4Srgb, 5, 4, 16, 4) },
|
||||
{ TextureFormat.Astc2D5x5UnormSrgb, new FormatInfo(Format.Astc5x5Srgb, 5, 5, 16, 4) },
|
||||
{ TextureFormat.Astc2D6x5UnormSrgb, new FormatInfo(Format.Astc6x5Srgb, 6, 5, 16, 4) },
|
||||
{ TextureFormat.Astc2D6x6UnormSrgb, new FormatInfo(Format.Astc6x6Srgb, 6, 6, 16, 4) },
|
||||
{ TextureFormat.Astc2D8x5UnormSrgb, new FormatInfo(Format.Astc8x5Srgb, 8, 5, 16, 4) },
|
||||
{ TextureFormat.Astc2D8x6UnormSrgb, new FormatInfo(Format.Astc8x6Srgb, 8, 6, 16, 4) },
|
||||
{ TextureFormat.Astc2D8x8UnormSrgb, new FormatInfo(Format.Astc8x8Srgb, 8, 8, 16, 4) },
|
||||
{ TextureFormat.Astc2D10x5UnormSrgb, new FormatInfo(Format.Astc10x5Srgb, 10, 5, 16, 4) },
|
||||
{ TextureFormat.Astc2D10x6UnormSrgb, new FormatInfo(Format.Astc10x6Srgb, 10, 6, 16, 4) },
|
||||
{ TextureFormat.Astc2D10x8UnormSrgb, new FormatInfo(Format.Astc10x8Srgb, 10, 8, 16, 4) },
|
||||
{ TextureFormat.Astc2D10x10UnormSrgb, new FormatInfo(Format.Astc10x10Srgb, 10, 10, 16, 4) },
|
||||
{ TextureFormat.Astc2D12x10UnormSrgb, new FormatInfo(Format.Astc12x10Srgb, 12, 10, 16, 4) },
|
||||
{ TextureFormat.Astc2D12x12UnormSrgb, new FormatInfo(Format.Astc12x12Srgb, 12, 12, 16, 4) },
|
||||
{ TextureFormat.A5B5G5R1Unorm, new FormatInfo(Format.A1B5G5R5Unorm, 1, 1, 2, 4) }
|
||||
};
|
||||
|
||||
private static Dictionary<ulong, Format> _attribFormats = new Dictionary<ulong, Format>()
|
||||
private static readonly Dictionary<VertexAttributeFormat, Format> _attribFormats = new Dictionary<VertexAttributeFormat, Format>()
|
||||
{
|
||||
{ 0x13a00000, Format.R8Unorm },
|
||||
{ 0x0ba00000, Format.R8Snorm },
|
||||
{ 0x23a00000, Format.R8Uint },
|
||||
{ 0x1ba00000, Format.R8Sint },
|
||||
{ 0x3b600000, Format.R16Float },
|
||||
{ 0x13600000, Format.R16Unorm },
|
||||
{ 0x0b600000, Format.R16Snorm },
|
||||
{ 0x23600000, Format.R16Uint },
|
||||
{ 0x1b600000, Format.R16Sint },
|
||||
{ 0x3a400000, Format.R32Float },
|
||||
{ 0x22400000, Format.R32Uint },
|
||||
{ 0x1a400000, Format.R32Sint },
|
||||
{ 0x13000000, Format.R8G8Unorm },
|
||||
{ 0x0b000000, Format.R8G8Snorm },
|
||||
{ 0x23000000, Format.R8G8Uint },
|
||||
{ 0x1b000000, Format.R8G8Sint },
|
||||
{ 0x39e00000, Format.R16G16Float },
|
||||
{ 0x11e00000, Format.R16G16Unorm },
|
||||
{ 0x09e00000, Format.R16G16Snorm },
|
||||
{ 0x21e00000, Format.R16G16Uint },
|
||||
{ 0x19e00000, Format.R16G16Sint },
|
||||
{ 0x38800000, Format.R32G32Float },
|
||||
{ 0x20800000, Format.R32G32Uint },
|
||||
{ 0x18800000, Format.R32G32Sint },
|
||||
{ 0x12600000, Format.R8G8B8Unorm },
|
||||
{ 0x0a600000, Format.R8G8B8Snorm },
|
||||
{ 0x22600000, Format.R8G8B8Uint },
|
||||
{ 0x1a600000, Format.R8G8B8Sint },
|
||||
{ 0x38a00000, Format.R16G16B16Float },
|
||||
{ 0x10a00000, Format.R16G16B16Unorm },
|
||||
{ 0x08a00000, Format.R16G16B16Snorm },
|
||||
{ 0x20a00000, Format.R16G16B16Uint },
|
||||
{ 0x18a00000, Format.R16G16B16Sint },
|
||||
{ 0x38400000, Format.R32G32B32Float },
|
||||
{ 0x20400000, Format.R32G32B32Uint },
|
||||
{ 0x18400000, Format.R32G32B32Sint },
|
||||
{ 0x11400000, Format.R8G8B8A8Unorm },
|
||||
{ 0x09400000, Format.R8G8B8A8Snorm },
|
||||
{ 0x21400000, Format.R8G8B8A8Uint },
|
||||
{ 0x19400000, Format.R8G8B8A8Sint },
|
||||
{ 0x38600000, Format.R16G16B16A16Float },
|
||||
{ 0x10600000, Format.R16G16B16A16Unorm },
|
||||
{ 0x08600000, Format.R16G16B16A16Snorm },
|
||||
{ 0x20600000, Format.R16G16B16A16Uint },
|
||||
{ 0x18600000, Format.R16G16B16A16Sint },
|
||||
{ 0x38200000, Format.R32G32B32A32Float },
|
||||
{ 0x20200000, Format.R32G32B32A32Uint },
|
||||
{ 0x18200000, Format.R32G32B32A32Sint },
|
||||
{ 0x16000000, Format.R10G10B10A2Unorm },
|
||||
{ 0x26000000, Format.R10G10B10A2Uint },
|
||||
{ 0x3e200000, Format.R11G11B10Float },
|
||||
{ 0x2ba00000, Format.R8Uscaled },
|
||||
{ 0x33a00000, Format.R8Sscaled },
|
||||
{ 0x2b600000, Format.R16Uscaled },
|
||||
{ 0x33600000, Format.R16Sscaled },
|
||||
{ 0x2a400000, Format.R32Uscaled },
|
||||
{ 0x32400000, Format.R32Sscaled },
|
||||
{ 0x2b000000, Format.R8G8Uscaled },
|
||||
{ 0x33000000, Format.R8G8Sscaled },
|
||||
{ 0x29e00000, Format.R16G16Uscaled },
|
||||
{ 0x31e00000, Format.R16G16Sscaled },
|
||||
{ 0x28800000, Format.R32G32Uscaled },
|
||||
{ 0x30800000, Format.R32G32Sscaled },
|
||||
{ 0x2a600000, Format.R8G8B8Uscaled },
|
||||
{ 0x32600000, Format.R8G8B8Sscaled },
|
||||
{ 0x28a00000, Format.R16G16B16Uscaled },
|
||||
{ 0x30a00000, Format.R16G16B16Sscaled },
|
||||
{ 0x28400000, Format.R32G32B32Uscaled },
|
||||
{ 0x30400000, Format.R32G32B32Sscaled },
|
||||
{ 0x29400000, Format.R8G8B8A8Uscaled },
|
||||
{ 0x31400000, Format.R8G8B8A8Sscaled },
|
||||
{ 0x28600000, Format.R16G16B16A16Uscaled },
|
||||
{ 0x30600000, Format.R16G16B16A16Sscaled },
|
||||
{ 0x28200000, Format.R32G32B32A32Uscaled },
|
||||
{ 0x30200000, Format.R32G32B32A32Sscaled },
|
||||
{ 0x0e000000, Format.R10G10B10A2Snorm },
|
||||
{ 0x1e000000, Format.R10G10B10A2Sint },
|
||||
{ 0x2e000000, Format.R10G10B10A2Uscaled },
|
||||
{ 0x36000000, Format.R10G10B10A2Sscaled }
|
||||
{ VertexAttributeFormat.R8Unorm, Format.R8Unorm },
|
||||
{ VertexAttributeFormat.R8Snorm, Format.R8Snorm },
|
||||
{ VertexAttributeFormat.R8Uint, Format.R8Uint },
|
||||
{ VertexAttributeFormat.R8Sint, Format.R8Sint },
|
||||
{ VertexAttributeFormat.R16Float, Format.R16Float },
|
||||
{ VertexAttributeFormat.R16Unorm, Format.R16Unorm },
|
||||
{ VertexAttributeFormat.R16Snorm, Format.R16Snorm },
|
||||
{ VertexAttributeFormat.R16Uint, Format.R16Uint },
|
||||
{ VertexAttributeFormat.R16Sint, Format.R16Sint },
|
||||
{ VertexAttributeFormat.R32Float, Format.R32Float },
|
||||
{ VertexAttributeFormat.R32Uint, Format.R32Uint },
|
||||
{ VertexAttributeFormat.R32Sint, Format.R32Sint },
|
||||
{ VertexAttributeFormat.R8G8Unorm, Format.R8G8Unorm },
|
||||
{ VertexAttributeFormat.R8G8Snorm, Format.R8G8Snorm },
|
||||
{ VertexAttributeFormat.R8G8Uint, Format.R8G8Uint },
|
||||
{ VertexAttributeFormat.R8G8Sint, Format.R8G8Sint },
|
||||
{ VertexAttributeFormat.R16G16Float, Format.R16G16Float },
|
||||
{ VertexAttributeFormat.R16G16Unorm, Format.R16G16Unorm },
|
||||
{ VertexAttributeFormat.R16G16Snorm, Format.R16G16Snorm },
|
||||
{ VertexAttributeFormat.R16G16Uint, Format.R16G16Uint },
|
||||
{ VertexAttributeFormat.R16G16Sint, Format.R16G16Sint },
|
||||
{ VertexAttributeFormat.R32G32Float, Format.R32G32Float },
|
||||
{ VertexAttributeFormat.R32G32Uint, Format.R32G32Uint },
|
||||
{ VertexAttributeFormat.R32G32Sint, Format.R32G32Sint },
|
||||
{ VertexAttributeFormat.R8G8B8Unorm, Format.R8G8B8Unorm },
|
||||
{ VertexAttributeFormat.R8G8B8Snorm, Format.R8G8B8Snorm },
|
||||
{ VertexAttributeFormat.R8G8B8Uint, Format.R8G8B8Uint },
|
||||
{ VertexAttributeFormat.R8G8B8Sint, Format.R8G8B8Sint },
|
||||
{ VertexAttributeFormat.R16G16B16Float, Format.R16G16B16Float },
|
||||
{ VertexAttributeFormat.R16G16B16Unorm, Format.R16G16B16Unorm },
|
||||
{ VertexAttributeFormat.R16G16B16Snorm, Format.R16G16B16Snorm },
|
||||
{ VertexAttributeFormat.R16G16B16Uint, Format.R16G16B16Uint },
|
||||
{ VertexAttributeFormat.R16G16B16Sint, Format.R16G16B16Sint },
|
||||
{ VertexAttributeFormat.R32G32B32Float, Format.R32G32B32Float },
|
||||
{ VertexAttributeFormat.R32G32B32Uint, Format.R32G32B32Uint },
|
||||
{ VertexAttributeFormat.R32G32B32Sint, Format.R32G32B32Sint },
|
||||
{ VertexAttributeFormat.R8G8B8A8Unorm, Format.R8G8B8A8Unorm },
|
||||
{ VertexAttributeFormat.R8G8B8A8Snorm, Format.R8G8B8A8Snorm },
|
||||
{ VertexAttributeFormat.R8G8B8A8Uint, Format.R8G8B8A8Uint },
|
||||
{ VertexAttributeFormat.R8G8B8A8Sint, Format.R8G8B8A8Sint },
|
||||
{ VertexAttributeFormat.R16G16B16A16Float, Format.R16G16B16A16Float },
|
||||
{ VertexAttributeFormat.R16G16B16A16Unorm, Format.R16G16B16A16Unorm },
|
||||
{ VertexAttributeFormat.R16G16B16A16Snorm, Format.R16G16B16A16Snorm },
|
||||
{ VertexAttributeFormat.R16G16B16A16Uint, Format.R16G16B16A16Uint },
|
||||
{ VertexAttributeFormat.R16G16B16A16Sint, Format.R16G16B16A16Sint },
|
||||
{ VertexAttributeFormat.R32G32B32A32Float, Format.R32G32B32A32Float },
|
||||
{ VertexAttributeFormat.R32G32B32A32Uint, Format.R32G32B32A32Uint },
|
||||
{ VertexAttributeFormat.R32G32B32A32Sint, Format.R32G32B32A32Sint },
|
||||
{ VertexAttributeFormat.A2B10G10R10Unorm, Format.R10G10B10A2Unorm },
|
||||
{ VertexAttributeFormat.A2B10G10R10Uint, Format.R10G10B10A2Uint },
|
||||
{ VertexAttributeFormat.B10G11R11Float, Format.R11G11B10Float },
|
||||
{ VertexAttributeFormat.R8Uscaled, Format.R8Uscaled },
|
||||
{ VertexAttributeFormat.R8Sscaled, Format.R8Sscaled },
|
||||
{ VertexAttributeFormat.R16Uscaled, Format.R16Uscaled },
|
||||
{ VertexAttributeFormat.R16Sscaled, Format.R16Sscaled },
|
||||
{ VertexAttributeFormat.R32Uscaled, Format.R32Uscaled },
|
||||
{ VertexAttributeFormat.R32Sscaled, Format.R32Sscaled },
|
||||
{ VertexAttributeFormat.R8G8Uscaled, Format.R8G8Uscaled },
|
||||
{ VertexAttributeFormat.R8G8Sscaled, Format.R8G8Sscaled },
|
||||
{ VertexAttributeFormat.R16G16Uscaled, Format.R16G16Uscaled },
|
||||
{ VertexAttributeFormat.R16G16Sscaled, Format.R16G16Sscaled },
|
||||
{ VertexAttributeFormat.R32G32Uscaled, Format.R32G32Uscaled },
|
||||
{ VertexAttributeFormat.R32G32Sscaled, Format.R32G32Sscaled },
|
||||
{ VertexAttributeFormat.R8G8B8Uscaled, Format.R8G8B8Uscaled },
|
||||
{ VertexAttributeFormat.R8G8B8Sscaled, Format.R8G8B8Sscaled },
|
||||
{ VertexAttributeFormat.R16G16B16Uscaled, Format.R16G16B16Uscaled },
|
||||
{ VertexAttributeFormat.R16G16B16Sscaled, Format.R16G16B16Sscaled },
|
||||
{ VertexAttributeFormat.R32G32B32Uscaled, Format.R32G32B32Uscaled },
|
||||
{ VertexAttributeFormat.R32G32B32Sscaled, Format.R32G32B32Sscaled },
|
||||
{ VertexAttributeFormat.R8G8B8A8Uscaled, Format.R8G8B8A8Uscaled },
|
||||
{ VertexAttributeFormat.R8G8B8A8Sscaled, Format.R8G8B8A8Sscaled },
|
||||
{ VertexAttributeFormat.R16G16B16A16Uscaled, Format.R16G16B16A16Uscaled },
|
||||
{ VertexAttributeFormat.R16G16B16A16Sscaled, Format.R16G16B16A16Sscaled },
|
||||
{ VertexAttributeFormat.R32G32B32A32Uscaled, Format.R32G32B32A32Uscaled },
|
||||
{ VertexAttributeFormat.R32G32B32A32Sscaled, Format.R32G32B32A32Sscaled },
|
||||
{ VertexAttributeFormat.A2B10G10R10Snorm, Format.R10G10B10A2Snorm },
|
||||
{ VertexAttributeFormat.A2B10G10R10Sint, Format.R10G10B10A2Sint },
|
||||
{ VertexAttributeFormat.A2B10G10R10Uscaled, Format.R10G10B10A2Uscaled },
|
||||
{ VertexAttributeFormat.A2B10G10R10Sscaled, Format.R10G10B10A2Sscaled }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@ -210,7 +557,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
encoded |= (isSrgb ? 1u << 19 : 0u);
|
||||
|
||||
return _textureFormats.TryGetValue(encoded, out format);
|
||||
return _textureFormats.TryGetValue((TextureFormat)encoded, out format);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -221,7 +568,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <returns>True if the format is valid, false otherwise</returns>
|
||||
public static bool TryGetAttribFormat(uint encoded, out Format format)
|
||||
{
|
||||
return _attribFormats.TryGetValue(encoded, out format);
|
||||
return _attribFormats.TryGetValue((VertexAttributeFormat)encoded, out format);
|
||||
}
|
||||
}
|
||||
}
|
@ -761,6 +761,24 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
_hasData = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uploads new texture data to the host GPU for a specific layer/level and 2D sub-region.
|
||||
/// </summary>
|
||||
/// <param name="data">New data</param>
|
||||
/// <param name="layer">Target layer</param>
|
||||
/// <param name="level">Target level</param>
|
||||
/// <param name="region">Target sub-region of the texture to update</param>
|
||||
public void SetData(ReadOnlySpan<byte> data, int layer, int level, Rectangle<int> region)
|
||||
{
|
||||
BlacklistScale();
|
||||
|
||||
HostTexture.SetData(data, layer, level, region);
|
||||
|
||||
_currentData = null;
|
||||
|
||||
_hasData = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts texture data to a format and layout that is supported by the host GPU.
|
||||
/// </summary>
|
||||
|
@ -47,6 +47,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
public int TextureHandle;
|
||||
public int SamplerHandle;
|
||||
public Format ImageFormat;
|
||||
public int InvalidatedSequence;
|
||||
public Texture CachedTexture;
|
||||
public Sampler CachedSampler;
|
||||
@ -564,6 +565,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
// Buffers are frequently re-created to accomodate larger data, so we need to re-bind
|
||||
// to ensure we're not using a old buffer that was already deleted.
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, bindingInfo.Format, false);
|
||||
|
||||
// Cache is not used for buffer texture, it must always rebind.
|
||||
state.CachedTexture = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -659,14 +663,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
cachedTexture?.SignalModified();
|
||||
}
|
||||
|
||||
if ((usageFlags & TextureUsageFlags.NeedsScaleValue) != 0 &&
|
||||
UpdateScale(state.CachedTexture, usageFlags, scaleIndex, stage))
|
||||
Format format = bindingInfo.Format == 0 ? cachedTexture.Format : bindingInfo.Format;
|
||||
|
||||
if (state.ImageFormat != format ||
|
||||
((usageFlags & TextureUsageFlags.NeedsScaleValue) != 0 &&
|
||||
UpdateScale(state.CachedTexture, usageFlags, scaleIndex, stage)))
|
||||
{
|
||||
ITexture hostTextureRebind = state.CachedTexture.GetTargetTexture(bindingInfo.Target);
|
||||
|
||||
Format format = bindingInfo.Format == 0 ? cachedTexture.Format : bindingInfo.Format;
|
||||
|
||||
state.Texture = hostTextureRebind;
|
||||
state.ImageFormat = format;
|
||||
|
||||
_context.Renderer.Pipeline.SetImage(bindingInfo.Binding, hostTextureRebind, format);
|
||||
}
|
||||
@ -696,6 +702,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
}
|
||||
|
||||
_channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, format, true);
|
||||
|
||||
// Cache is not used for buffer texture, it must always rebind.
|
||||
state.CachedTexture = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -721,6 +730,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
format = texture.Format;
|
||||
}
|
||||
|
||||
state.ImageFormat = format;
|
||||
|
||||
_context.Renderer.Pipeline.SetImage(bindingInfo.Binding, hostTexture, format);
|
||||
}
|
||||
|
||||
|
@ -905,7 +905,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// <param name="xCount">Number of pixels to be copied per line</param>
|
||||
/// <param name="yCount">Number of lines to be copied</param>
|
||||
/// <param name="linear">True if the texture has a linear layout, false otherwise</param>
|
||||
/// <param name="memoryLayout">If <paramref name="linear"/> is false, should have the memory layout, otherwise ignored</param>
|
||||
/// <param name="gobBlocksInY">If <paramref name="linear"/> is false, the amount of GOB blocks in the Y axis</param>
|
||||
/// <param name="gobBlocksInZ">If <paramref name="linear"/> is false, the amount of GOB blocks in the Z axis</param>
|
||||
/// <returns>A matching texture, or null if there is no match</returns>
|
||||
public Texture FindTexture(
|
||||
MemoryManager memoryManager,
|
||||
@ -916,7 +917,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
int xCount,
|
||||
int yCount,
|
||||
bool linear,
|
||||
MemoryLayout memoryLayout)
|
||||
int gobBlocksInY,
|
||||
int gobBlocksInZ)
|
||||
{
|
||||
ulong address = memoryManager.Translate(gpuVa);
|
||||
|
||||
@ -955,8 +957,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
bool sizeMatch = xCount * bpp == texture.Info.Width * format.BytesPerPixel && height == texture.Info.Height;
|
||||
bool formatMatch = !texture.Info.IsLinear &&
|
||||
texture.Info.GobBlocksInY == memoryLayout.UnpackGobBlocksInY() &&
|
||||
texture.Info.GobBlocksInZ == memoryLayout.UnpackGobBlocksInZ();
|
||||
texture.Info.GobBlocksInY == gobBlocksInY &&
|
||||
texture.Info.GobBlocksInZ == gobBlocksInZ;
|
||||
|
||||
match = sizeMatch && formatMatch;
|
||||
}
|
||||
|
@ -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 = 3525;
|
||||
private const uint CodeGenVersion = 3644;
|
||||
|
||||
private const string SharedTocFileName = "shared.toc";
|
||||
private const string SharedDataFileName = "shared.data";
|
||||
@ -827,4 +827,4 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,6 +134,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
|
||||
public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
|
||||
|
||||
public bool QueryHostSupportsViewportIndex() => _context.Capabilities.SupportsViewportIndex;
|
||||
|
||||
/// <summary>
|
||||
/// Converts a packed Maxwell texture format to the shader translator texture format.
|
||||
/// </summary>
|
||||
|
@ -58,6 +58,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void SetData(ReadOnlySpan<byte> data, int layer, int level, Rectangle<int> region)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void SetStorage(BufferRange buffer)
|
||||
{
|
||||
if (_buffer != BufferHandle.Null &&
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user