aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChocolArm64/AOpCodeTable.cs1
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs8
-rw-r--r--ChocolArm64/Instruction/ASoftFallback.cs22
-rw-r--r--Ryujinx.Graphics/Gal/GalTextureFormat.cs1
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs1
-rw-r--r--Ryujinx.Graphics/Gal/Shader/GlslDecl.cs3
-rw-r--r--Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs3
-rw-r--r--Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs2
-rw-r--r--Ryujinx.HLE/Gpu/NvGpu.cs10
-rw-r--r--Ryujinx.HLE/Gpu/NvGpuEngineDma.cs142
-rw-r--r--Ryujinx.HLE/Gpu/NvGpuEngineDmaReg.cs22
-rw-r--r--Ryujinx.HLE/Gpu/NvGpuFifo.cs10
-rw-r--r--Ryujinx.HLE/Gpu/TextureHelper.cs1
-rw-r--r--Ryujinx.HLE/Gpu/TextureReader.cs1
-rw-r--r--Ryujinx.HLE/Hid/Hid.cs6
-rw-r--r--Ryujinx.HLE/OsHle/Services/Am/ICommonStateGetter.cs37
-rw-r--r--Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlService.cs25
-rw-r--r--Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlServiceFactory.cs12
-rw-r--r--Ryujinx.HLE/OsHle/Services/Set/ISettingsServer.cs40
19 files changed, 308 insertions, 39 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs
index 3500fba0..5bddc3b9 100644
--- a/ChocolArm64/AOpCodeTable.cs
+++ b/ChocolArm64/AOpCodeTable.cs
@@ -206,6 +206,7 @@ namespace ChocolArm64
SetA64("0>101110000xxxxx0<xxx0xxxxxxxxxx", AInstEmit.Ext_V, typeof(AOpCodeSimdExt));
SetA64("011111101x1xxxxx110101xxxxxxxxxx", AInstEmit.Fabd_S, typeof(AOpCodeSimdReg));
SetA64("000111100x100000110000xxxxxxxxxx", AInstEmit.Fabs_S, typeof(AOpCodeSimd));
+ SetA64("0>0011101<100000111110xxxxxxxxxx", AInstEmit.Fabs_V, typeof(AOpCodeSimd));
SetA64("000111100x1xxxxx001010xxxxxxxxxx", AInstEmit.Fadd_S, typeof(AOpCodeSimdReg));
SetA64("0>0011100<1xxxxx110101xxxxxxxxxx", AInstEmit.Fadd_V, typeof(AOpCodeSimdReg));
SetA64("0>1011100<1xxxxx110101xxxxxxxxxx", AInstEmit.Faddp_V, typeof(AOpCodeSimdReg));
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index 0dfe0bd3..5aea6b04 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -309,6 +309,14 @@ namespace ChocolArm64.Instruction
});
}
+ public static void Fabs_V(AILEmitterCtx Context)
+ {
+ EmitVectorUnaryOpF(Context, () =>
+ {
+ EmitUnaryMathCall(Context, nameof(Math.Abs));
+ });
+ }
+
public static void Fadd_S(AILEmitterCtx Context)
{
if (AOptimizations.UseSse2)
diff --git a/ChocolArm64/Instruction/ASoftFallback.cs b/ChocolArm64/Instruction/ASoftFallback.cs
index 8ed55e20..3f8ab5e3 100644
--- a/ChocolArm64/Instruction/ASoftFallback.cs
+++ b/ChocolArm64/Instruction/ASoftFallback.cs
@@ -153,12 +153,30 @@ namespace ChocolArm64.Instruction
public static long SMulHi128(long LHS, long RHS)
{
- return (long)(BigInteger.Multiply(LHS, RHS) >> 64);
+ bool LSign = (LHS < 0);
+ bool RSign = (RHS < 0);
+
+ long Result = (long)UMulHi128((ulong)(LSign ? -LHS : LHS), (ulong)(RSign ? -RHS : RHS));
+
+ if (LSign != RSign && LHS != 0 && RHS != 0)
+ return ~Result; //for negative results, hi 64-bits start at 0xFFF... and count back
+ return Result;
}
public static ulong UMulHi128(ulong LHS, ulong RHS)
{
- return (ulong)(BigInteger.Multiply(LHS, RHS) >> 64);
+ //long multiplication
+ //multiply 32 bits at a time in 64 bit, the result is what's carried over 64 bits.
+ ulong LHigh = LHS >> 32;
+ ulong LLow = LHS & 0xFFFFFFFF;
+ ulong RHigh = RHS >> 32;
+ ulong RLow = RHS & 0xFFFFFFFF;
+ ulong Z2 = LLow * RLow;
+ ulong T = LHigh * RLow + (Z2 >> 32);
+ ulong Z1 = T & 0xFFFFFFFF;
+ ulong Z0 = T >> 32;
+ Z1 += LLow * RHigh;
+ return LHigh * RHigh + Z0 + (Z1 >> 32);
}
}
}
diff --git a/Ryujinx.Graphics/Gal/GalTextureFormat.cs b/Ryujinx.Graphics/Gal/GalTextureFormat.cs
index 3bac2f80..7d19dc26 100644
--- a/Ryujinx.Graphics/Gal/GalTextureFormat.cs
+++ b/Ryujinx.Graphics/Gal/GalTextureFormat.cs
@@ -10,6 +10,7 @@ namespace Ryujinx.Graphics.Gal
B5G6R5 = 0x15,
BC7U = 0x17,
G8R8 = 0x18,
+ R16 = 0x1b,
R8 = 0x1d,
BC1 = 0x24,
BC2 = 0x25,
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
index 50b802c1..c8000603 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
@@ -66,6 +66,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalTextureFormat.A1B5G5R5: return (PixelFormat.Rgba, PixelType.UnsignedShort5551);
case GalTextureFormat.B5G6R5: return (PixelFormat.Rgb, PixelType.UnsignedShort565);
case GalTextureFormat.G8R8: return (PixelFormat.Rg, PixelType.UnsignedByte);
+ case GalTextureFormat.R16: return (PixelFormat.Red, PixelType.HalfFloat);
case GalTextureFormat.R8: return (PixelFormat.Red, PixelType.UnsignedByte);
}
diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
index 43a04813..4002c29a 100644
--- a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
+++ b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
@@ -159,7 +159,8 @@ namespace Ryujinx.Graphics.Gal.Shader
case ShaderIrOperAbuf Abuf:
{
//This is a built-in input variable.
- if (Abuf.Offs == VertexIdAttr)
+ if (Abuf.Offs == VertexIdAttr ||
+ Abuf.Offs == InstanceIdAttr)
{
break;
}
diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
index 71a53a5a..1bcedacb 100644
--- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
+++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
@@ -975,7 +975,8 @@ namespace Ryujinx.Graphics.Gal.Shader
switch (Node)
{
case ShaderIrOperAbuf Abuf:
- return Abuf.Offs == GlslDecl.VertexIdAttr
+ return Abuf.Offs == GlslDecl.VertexIdAttr ||
+ Abuf.Offs == GlslDecl.InstanceIdAttr
? OperType.I32
: OperType.F32;
diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
index 3299ebab..a8ad5ec2 100644
--- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
+++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs
@@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Gal.Shader
for (int Index = 0; Index <= Size; Index++)
{
- Opers[Index] = new ShaderIrOperAbuf(Abuf, Reg);
+ Opers[Index] = new ShaderIrOperAbuf(Abuf + Index * 4, Reg);
}
return Opers;
diff --git a/Ryujinx.HLE/Gpu/NvGpu.cs b/Ryujinx.HLE/Gpu/NvGpu.cs
index 1e433fa4..0301fcf2 100644
--- a/Ryujinx.HLE/Gpu/NvGpu.cs
+++ b/Ryujinx.HLE/Gpu/NvGpu.cs
@@ -9,8 +9,9 @@ namespace Ryujinx.HLE.Gpu
public NvGpuFifo Fifo { get; private set; }
- public NvGpuEngine2d Engine2d { get; private set; }
- public NvGpuEngine3d Engine3d { get; private set; }
+ public NvGpuEngine2d Engine2d { get; private set; }
+ public NvGpuEngine3d Engine3d { get; private set; }
+ public NvGpuEngineDma EngineDma { get; private set; }
private Thread FifoProcessing;
@@ -22,8 +23,9 @@ namespace Ryujinx.HLE.Gpu
Fifo = new NvGpuFifo(this);
- Engine2d = new NvGpuEngine2d(this);
- Engine3d = new NvGpuEngine3d(this);
+ Engine2d = new NvGpuEngine2d(this);
+ Engine3d = new NvGpuEngine3d(this);
+ EngineDma = new NvGpuEngineDma(this);
KeepRunning = true;
diff --git a/Ryujinx.HLE/Gpu/NvGpuEngineDma.cs b/Ryujinx.HLE/Gpu/NvGpuEngineDma.cs
new file mode 100644
index 00000000..48a19047
--- /dev/null
+++ b/Ryujinx.HLE/Gpu/NvGpuEngineDma.cs
@@ -0,0 +1,142 @@
+using Ryujinx.Graphics.Gal;
+using System.Collections.Generic;
+
+namespace Ryujinx.HLE.Gpu
+{
+ class NvGpuEngineDma : INvGpuEngine
+ {
+ public int[] Registers { get; private set; }
+
+ private NvGpu Gpu;
+
+ private Dictionary<int, NvGpuMethod> Methods;
+
+ public NvGpuEngineDma(NvGpu Gpu)
+ {
+ this.Gpu = Gpu;
+
+ Registers = new int[0x1d6];
+
+ Methods = new Dictionary<int, NvGpuMethod>();
+
+ void AddMethod(int Meth, int Count, int Stride, NvGpuMethod Method)
+ {
+ while (Count-- > 0)
+ {
+ Methods.Add(Meth, Method);
+
+ Meth += Stride;
+ }
+ }
+
+ AddMethod(0xc0, 1, 1, Execute);
+ }
+
+ public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
+ {
+ if (Methods.TryGetValue(PBEntry.Method, out NvGpuMethod Method))
+ {
+ Method(Vmm, PBEntry);
+ }
+ else
+ {
+ WriteRegister(PBEntry);
+ }
+ }
+
+ private void Execute(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
+ {
+ int Control = PBEntry.Arguments[0];
+
+ bool SrcLinear = ((Control >> 7) & 1) != 0;
+ bool DstLinear = ((Control >> 8) & 1) != 0;
+
+ long SrcAddress = MakeInt64From2xInt32(NvGpuEngineDmaReg.SrcAddress);
+ long DstAddress = MakeInt64From2xInt32(NvGpuEngineDmaReg.DstAddress);
+
+ int SrcPitch = ReadRegister(NvGpuEngineDmaReg.SrcPitch);
+ int DstPitch = ReadRegister(NvGpuEngineDmaReg.DstPitch);
+
+ int DstBlkDim = ReadRegister(NvGpuEngineDmaReg.DstBlkDim);
+ int DstSizeX = ReadRegister(NvGpuEngineDmaReg.DstSizeX);
+ int DstSizeY = ReadRegister(NvGpuEngineDmaReg.DstSizeY);
+ int DstSizeZ = ReadRegister(NvGpuEngineDmaReg.DstSizeZ);
+ int DstPosXY = ReadRegister(NvGpuEngineDmaReg.DstPosXY);
+ int DstPosZ = ReadRegister(NvGpuEngineDmaReg.DstPosZ);
+
+ int SrcBlkDim = ReadRegister(NvGpuEngineDmaReg.SrcBlkDim);
+ int SrcSizeX = ReadRegister(NvGpuEngineDmaReg.SrcSizeX);
+ int SrcSizeY = ReadRegister(NvGpuEngineDmaReg.SrcSizeY);
+ int SrcSizeZ = ReadRegister(NvGpuEngineDmaReg.SrcSizeZ);
+ int SrcPosXY = ReadRegister(NvGpuEngineDmaReg.SrcPosXY);
+ int SrcPosZ = ReadRegister(NvGpuEngineDmaReg.SrcPosZ);
+
+ int DstPosX = (DstPosXY >> 0) & 0xffff;
+ int DstPosY = (DstPosXY >> 16) & 0xffff;
+
+ int SrcPosX = (SrcPosXY >> 0) & 0xffff;
+ int SrcPosY = (SrcPosXY >> 16) & 0xffff;
+
+ int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf);
+ int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);
+
+ ISwizzle SrcSwizzle;
+
+ if (SrcLinear)
+ {
+ SrcSwizzle = new LinearSwizzle(SrcPitch, 1);
+ }
+ else
+ {
+ SrcSwizzle = new BlockLinearSwizzle(SrcSizeX, 1, SrcBlockHeight);
+ }
+
+ ISwizzle DstSwizzle;
+
+ if (DstLinear)
+ {
+ DstSwizzle = new LinearSwizzle(DstPitch, 1);
+ }
+ else
+ {
+ DstSwizzle = new BlockLinearSwizzle(DstSizeX, 1, DstBlockHeight);
+ }
+
+ for (int Y = 0; Y < DstSizeY; Y++)
+ for (int X = 0; X < DstSizeX; X++)
+ {
+ long SrcOffset = SrcAddress + (uint)SrcSwizzle.GetSwizzleOffset(X, Y);
+ long DstOffset = DstAddress + (uint)DstSwizzle.GetSwizzleOffset(X, Y);
+
+ Vmm.WriteByte(DstOffset, Vmm.ReadByte(SrcOffset));
+ }
+ }
+
+ private long MakeInt64From2xInt32(NvGpuEngineDmaReg Reg)
+ {
+ return
+ (long)Registers[(int)Reg + 0] << 32 |
+ (uint)Registers[(int)Reg + 1];
+ }
+
+ private void WriteRegister(NvGpuPBEntry PBEntry)
+ {
+ int ArgsCount = PBEntry.Arguments.Count;
+
+ if (ArgsCount > 0)
+ {
+ Registers[PBEntry.Method] = PBEntry.Arguments[ArgsCount - 1];
+ }
+ }
+
+ private int ReadRegister(NvGpuEngineDmaReg Reg)
+ {
+ return Registers[(int)Reg];
+ }
+
+ private void WriteRegister(NvGpuEngineDmaReg Reg, int Value)
+ {
+ Registers[(int)Reg] = Value;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/Gpu/NvGpuEngineDmaReg.cs b/Ryujinx.HLE/Gpu/NvGpuEngineDmaReg.cs
new file mode 100644
index 00000000..55b404c5
--- /dev/null
+++ b/Ryujinx.HLE/Gpu/NvGpuEngineDmaReg.cs
@@ -0,0 +1,22 @@
+namespace Ryujinx.HLE.Gpu
+{
+ enum NvGpuEngineDmaReg
+ {
+ SrcAddress = 0x100,
+ DstAddress = 0x102,
+ SrcPitch = 0x104,
+ DstPitch = 0x105,
+ DstBlkDim = 0x1c3,
+ DstSizeX = 0x1c4,
+ DstSizeY = 0x1c5,
+ DstSizeZ = 0x1c6,
+ DstPosZ = 0x1c7,
+ DstPosXY = 0x1c8,
+ SrcBlkDim = 0x1ca,
+ SrcSizeX = 0x1cb,
+ SrcSizeY = 0x1cc,
+ SrcSizeZ = 0x1cd,
+ SrcPosZ = 0x1ce,
+ SrcPosXY = 0x1cf
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/Gpu/NvGpuFifo.cs b/Ryujinx.HLE/Gpu/NvGpuFifo.cs
index 0df37edc..f115e8db 100644
--- a/Ryujinx.HLE/Gpu/NvGpuFifo.cs
+++ b/Ryujinx.HLE/Gpu/NvGpuFifo.cs
@@ -136,8 +136,9 @@ namespace Ryujinx.HLE.Gpu
{
switch (SubChannels[PBEntry.SubChannel])
{
- case NvGpuEngine._2d: Call2dMethod(Vmm, PBEntry); break;
- case NvGpuEngine._3d: Call3dMethod(Vmm, PBEntry); break;
+ case NvGpuEngine._2d: Call2dMethod (Vmm, PBEntry); break;
+ case NvGpuEngine._3d: Call3dMethod (Vmm, PBEntry); break;
+ case NvGpuEngine.Dma: CallDmaMethod(Vmm, PBEntry); break;
}
}
}
@@ -170,5 +171,10 @@ namespace Ryujinx.HLE.Gpu
}
}
}
+
+ private void CallDmaMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
+ {
+ Gpu.EngineDma.CallMethod(Vmm, PBEntry);
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/Gpu/TextureHelper.cs b/Ryujinx.HLE/Gpu/TextureHelper.cs
index f1b3f0b3..e48e25ad 100644
--- a/Ryujinx.HLE/Gpu/TextureHelper.cs
+++ b/Ryujinx.HLE/Gpu/TextureHelper.cs
@@ -33,6 +33,7 @@ namespace Ryujinx.HLE.Gpu
case GalTextureFormat.A1B5G5R5: return Texture.Width * Texture.Height * 2;
case GalTextureFormat.B5G6R5: return Texture.Width * Texture.Height * 2;
case GalTextureFormat.G8R8: return Texture.Width * Texture.Height * 2;
+ case GalTextureFormat.R16: return Texture.Width * Texture.Height * 2;
case GalTextureFormat.R8: return Texture.Width * Texture.Height;
case GalTextureFormat.BC1:
diff --git a/Ryujinx.HLE/Gpu/TextureReader.cs b/Ryujinx.HLE/Gpu/TextureReader.cs
index 4436e07f..9e9ff783 100644
--- a/Ryujinx.HLE/Gpu/TextureReader.cs
+++ b/Ryujinx.HLE/Gpu/TextureReader.cs
@@ -17,6 +17,7 @@ namespace Ryujinx.HLE.Gpu
case GalTextureFormat.A1B5G5R5: return Read5551 (Memory, Texture);
case GalTextureFormat.B5G6R5: return Read565 (Memory, Texture);
case GalTextureFormat.G8R8: return Read2Bpp (Memory, Texture);
+ case GalTextureFormat.R16: return Read2Bpp (Memory, Texture);
case GalTextureFormat.R8: return Read1Bpp (Memory, Texture);
case GalTextureFormat.BC7U: return Read16Bpt4x4(Memory, Texture);
case GalTextureFormat.BC1: return Read8Bpt4x4 (Memory, Texture);
diff --git a/Ryujinx.HLE/Hid/Hid.cs b/Ryujinx.HLE/Hid/Hid.cs
index 054c4fac..2f007f1f 100644
--- a/Ryujinx.HLE/Hid/Hid.cs
+++ b/Ryujinx.HLE/Hid/Hid.cs
@@ -130,9 +130,7 @@ namespace Ryujinx.HLE.Input
{
long BaseControllerOffset = Position + HidControllersOffset + 8 * HidControllerSize;
- HidControllerType Type =
- HidControllerType.ControllerType_Handheld |
- HidControllerType.ControllerType_JoyconPair;
+ HidControllerType Type = HidControllerType.ControllerType_Handheld;
bool IsHalf = false;
@@ -276,4 +274,4 @@ namespace Ryujinx.HLE.Input
return (long)((ulong)Environment.TickCount * 19_200);
}
}
-} \ No newline at end of file
+}
diff --git a/Ryujinx.HLE/OsHle/Services/Am/ICommonStateGetter.cs b/Ryujinx.HLE/OsHle/Services/Am/ICommonStateGetter.cs
index 2b575cb7..e1a13c59 100644
--- a/Ryujinx.HLE/OsHle/Services/Am/ICommonStateGetter.cs
+++ b/Ryujinx.HLE/OsHle/Services/Am/ICommonStateGetter.cs
@@ -13,17 +13,23 @@ namespace Ryujinx.HLE.OsHle.Services.Am
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+ private KEvent DisplayResolutionChangeEvent;
+
public ICommonStateGetter()
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
- { 0, GetEventHandle },
- { 1, ReceiveMessage },
- { 5, GetOperationMode },
- { 6, GetPerformanceMode },
- { 8, GetBootMode },
- { 9, GetCurrentFocusState }
+ { 0, GetEventHandle },
+ { 1, ReceiveMessage },
+ { 5, GetOperationMode },
+ { 6, GetPerformanceMode },
+ { 8, GetBootMode },
+ { 9, GetCurrentFocusState },
+ { 60, GetDefaultDisplayResolution },
+ { 61, GetDefaultDisplayResolutionChangeEvent }
};
+
+ DisplayResolutionChangeEvent = new KEvent();
}
public long GetEventHandle(ServiceCtx Context)
@@ -78,5 +84,24 @@ namespace Ryujinx.HLE.OsHle.Services.Am
return 0;
}
+
+ public long GetDefaultDisplayResolution(ServiceCtx Context)
+ {
+ Context.ResponseData.Write(1280);
+ Context.ResponseData.Write(720);
+
+ return 0;
+ }
+
+ public long GetDefaultDisplayResolutionChangeEvent(ServiceCtx Context)
+ {
+ int Handle = Context.Process.HandleTable.OpenHandle(DisplayResolutionChangeEvent);
+
+ Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
+
+ Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed.");
+
+ return 0;
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlService.cs b/Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlService.cs
index eb363ade..60a69f58 100644
--- a/Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlService.cs
+++ b/Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlService.cs
@@ -1,3 +1,4 @@
+using Ryujinx.HLE.Logging;
using Ryujinx.HLE.OsHle.Ipc;
using System.Collections.Generic;
@@ -9,12 +10,32 @@ namespace Ryujinx.HLE.OsHle.Services.Pctl
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
- public IParentalControlService()
+ private bool Initialized = false;
+
+ private bool NeedInitialize;
+
+ public IParentalControlService(bool NeedInitialize = true)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
- //...
+ { 1, Initialize }
};
+
+ this.NeedInitialize = NeedInitialize;
+ }
+
+ public long Initialize(ServiceCtx Context)
+ {
+ if (NeedInitialize && !Initialized)
+ {
+ Initialized = true;
+ }
+ else
+ {
+ Context.Ns.Log.PrintWarning(LogClass.ServicePctl, "Service is already initialized!");
+ }
+
+ return 0;
}
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlServiceFactory.cs b/Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlServiceFactory.cs
index 094245f6..7ef91d7f 100644
--- a/Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlServiceFactory.cs
+++ b/Ryujinx.HLE/OsHle/Services/Pctl/IParentalControlServiceFactory.cs
@@ -13,15 +13,23 @@ namespace Ryujinx.HLE.OsHle.Services.Pctl
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
- { 0, CreateService }
+ { 0, CreateService },
+ { 1, CreateServiceWithoutInitialize }
};
}
- public static long CreateService(ServiceCtx Context)
+ public long CreateService(ServiceCtx Context)
{
MakeObject(Context, new IParentalControlService());
return 0;
}
+
+ public long CreateServiceWithoutInitialize(ServiceCtx Context)
+ {
+ MakeObject(Context, new IParentalControlService(false));
+
+ return 0;
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/OsHle/Services/Set/ISettingsServer.cs b/Ryujinx.HLE/OsHle/Services/Set/ISettingsServer.cs
index 96297ad2..abab9382 100644
--- a/Ryujinx.HLE/OsHle/Services/Set/ISettingsServer.cs
+++ b/Ryujinx.HLE/OsHle/Services/Set/ISettingsServer.cs
@@ -15,7 +15,8 @@ namespace Ryujinx.HLE.OsHle.Services.Set
{
{ 0, GetLanguageCode },
{ 1, GetAvailableLanguageCodes },
- { 3, GetAvailableLanguageCodeCount }
+ { 3, GetAvailableLanguageCodeCount },
+ { 5, GetAvailableLanguageCodes2 }
};
}
@@ -27,10 +28,28 @@ namespace Ryujinx.HLE.OsHle.Services.Set
}
public static long GetAvailableLanguageCodes(ServiceCtx Context)
+ {
+ GetAvailableLanguagesCodesMethod(Context, Context.Request.RecvListBuff[0].Position, Context.Request.RecvListBuff[0].Size);
+
+ return 0;
+ }
+
+ public static long GetAvailableLanguageCodeCount(ServiceCtx Context)
{
- long Position = Context.Request.RecvListBuff[0].Position;
- long Size = Context.Request.RecvListBuff[0].Size;
+ Context.ResponseData.Write(SystemStateMgr.LanguageCodes.Length);
+ return 0;
+ }
+
+ public static long GetAvailableLanguageCodes2(ServiceCtx Context)
+ {
+ GetAvailableLanguagesCodesMethod(Context, Context.Request.ReceiveBuff[0].Position, Context.Request.ReceiveBuff[0].Size);
+
+ return 0;
+ }
+
+ public static long GetAvailableLanguagesCodesMethod(ServiceCtx Context, long Position, long Size)
+ {
int Count = (int)(Size / 8);
if (Count > SystemStateMgr.LanguageCodes.Length)
@@ -46,15 +65,8 @@ namespace Ryujinx.HLE.OsHle.Services.Set
}
Context.ResponseData.Write(Count);
-
- return 0;
- }
-
- public static long GetAvailableLanguageCodeCount(ServiceCtx Context)
- {
- Context.ResponseData.Write(SystemStateMgr.LanguageCodes.Length);
-
- return 0;
- }
+
+ return 0;
+ }
}
-} \ No newline at end of file
+}