From 9754836c1bf512c3be4a08a21024a4ed7ae745f7 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 4 Apr 2018 21:01:36 -0300 Subject: [PATCH] Fix GetAvailableLanguageCodes, stub ListAddOnContent and NvGpuAsIoctlRemap (0x4114) --- Ryujinx.Core/OsHle/Ipc/IpcHandler.cs | 6 +-- Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs | 12 ++++- .../OsHle/Services/Nv/ServiceNvDrv.cs | 47 +++++++++++++--- Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs | 54 ++++++++++++++----- Ryujinx.Core/OsHle/Svc/SvcSystem.cs | 4 +- 5 files changed, 96 insertions(+), 27 deletions(-) diff --git a/Ryujinx.Core/OsHle/Ipc/IpcHandler.cs b/Ryujinx.Core/OsHle/Ipc/IpcHandler.cs index 35a2535be..42322d41a 100644 --- a/Ryujinx.Core/OsHle/Ipc/IpcHandler.cs +++ b/Ryujinx.Core/OsHle/Ipc/IpcHandler.cs @@ -61,12 +61,12 @@ namespace Ryujinx.Core.OsHle.Ipc case 3: { Request = FillResponse(Response, 0, 0x500); - + break; } - //TODO: Whats the difference between IpcDuplicateSession/Ex? - case 2: + //TODO: Whats the difference between IpcDuplicateSession/Ex? + case 2: case 4: { int Unknown = ReqReader.ReadInt32(); diff --git a/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs b/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs index c28ecc7ab..5e00a0f6c 100644 --- a/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs +++ b/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs @@ -13,7 +13,8 @@ namespace Ryujinx.Core.OsHle.Services.Ns { m_Commands = new Dictionary() { - { 2, CountAddOnContent } + { 2, CountAddOnContent }, + { 3, ListAddOnContent } }; } @@ -23,5 +24,14 @@ namespace Ryujinx.Core.OsHle.Services.Ns return 0; } + + public static long ListAddOnContent(ServiceCtx Context) + { + //TODO: This is supposed to write a u32 array aswell. + //It's unknown what it contains. + Context.ResponseData.Write(0); + + return 0; + } } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs index 2c909b3ac..f877fb9c7 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs @@ -5,6 +5,7 @@ using Ryujinx.Core.OsHle.Utilities; using Ryujinx.Graphics.Gpu; using System; using System.Collections.Generic; +using System.IO; namespace Ryujinx.Core.OsHle.Services.Nv { @@ -45,6 +46,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv { ("/dev/nvhost-as-gpu", 0x4106), NvGpuAsIoctlMapBufferEx }, { ("/dev/nvhost-as-gpu", 0x4108), NvGpuAsIoctlGetVaRegions }, { ("/dev/nvhost-as-gpu", 0x4109), NvGpuAsIoctlInitializeEx }, + { ("/dev/nvhost-as-gpu", 0x4114), NvGpuAsIoctlRemap }, { ("/dev/nvhost-ctrl", 0x001b), NvHostIoctlCtrlGetConfig }, { ("/dev/nvhost-ctrl", 0x001d), NvHostIoctlCtrlEventWait }, { ("/dev/nvhost-ctrl-gpu", 0x4701), NvGpuIoctlZcullGetCtxSize }, @@ -98,7 +100,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv { int Fd = Context.RequestData.ReadInt32(); int Cmd = Context.RequestData.ReadInt32() & 0xffff; - + NvFd FdData = Fds.GetData(Context.Process, Fd); long Position = Context.Request.GetSendBuffPtr(); @@ -206,7 +208,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv int Flags = Reader.ReadInt32(); int Kind = Reader.ReadInt32(); int Handle = Reader.ReadInt32(); - int PageSize = Reader.ReadInt32(); + int PageSize = Reader.ReadInt32(); long BuffAddr = Reader.ReadInt64(); long MapSize = Reader.ReadInt64(); long Offset = Reader.ReadInt64(); @@ -226,7 +228,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - + return -1; //TODO: Corrent error code. } @@ -291,6 +293,35 @@ namespace Ryujinx.Core.OsHle.Services.Nv return 0; } + private long NvGpuAsIoctlRemap(ServiceCtx Context) + { + Context.RequestData.BaseStream.Seek(-4, SeekOrigin.Current); + + int Cmd = Context.RequestData.ReadInt32(); + + int Size = (Cmd >> 16) & 0xff; + + int Count = Size / 0x18; + + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + for (int Index = 0; Index < Count; Index++) + { + int Flags = Reader.ReadInt32(); + int Kind = Reader.ReadInt32(); + int Handle = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + int Offset = Reader.ReadInt32(); + int Pages = Reader.ReadInt32(); + } + + //TODO + + return 0; + } + private long NvHostIoctlCtrlGetConfig(ServiceCtx Context) { long Position = Context.Request.GetSendBuffPtr(); @@ -590,7 +621,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { Logging.Warn($"Trying to use invalid NvMap Id {Id}!"); - + return -1; //TODO: Corrent error code. } @@ -617,7 +648,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - + return -1; //TODO: Corrent error code. } @@ -643,7 +674,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - + return -1; //TODO: Corrent error code. } @@ -668,7 +699,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - + return -1; //TODO: Corrent error code. } @@ -698,7 +729,7 @@ namespace Ryujinx.Core.OsHle.Services.Nv if (Map == null) { Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - + return -1; //TODO: Corrent error code. } diff --git a/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs b/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs index 95845e316..a2aaeeafb 100644 --- a/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs +++ b/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs @@ -1,12 +1,31 @@ -using ChocolArm64.Memory; using Ryujinx.Core.OsHle.Ipc; -using System; using System.Collections.Generic; namespace Ryujinx.Core.OsHle.Services.Set { class ServiceSet : IpcService { + private static string[] LanguageCodes = new string[] + { + "ja", + "en-US", + "fr", + "de", + "it", + "es", + "zh-CN", + "ko", + "nl", + "pt", + "ru", + "zh-TW", + "en-GB", + "fr-CA", + "es-419", + "zh-Hans", + "zh-Hant" + }; + private Dictionary m_Commands; public override IReadOnlyDictionary Commands => m_Commands; @@ -20,32 +39,41 @@ namespace Ryujinx.Core.OsHle.Services.Set }; } - private const int LangCodesCount = 13; - public static long GetAvailableLanguageCodes(ServiceCtx Context) { - int PtrBuffSize = Context.RequestData.ReadInt32(); + long Position = Context.Request.RecvListBuff[0].Position; + short Size = Context.Request.RecvListBuff[0].Size; - if (Context.Request.RecvListBuff.Count > 0) + int Count = (int)((uint)Size / 8); + + if (Count > LanguageCodes.Length) { - long Position = Context.Request.RecvListBuff[0].Position; - short Size = Context.Request.RecvListBuff[0].Size; + Count = LanguageCodes.Length; + } - //This should return an array of ints with values matching the LanguageCode enum. - foreach (long value in new long[] { 0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L }) + for (int Index = 0; Index < Count; Index++) + { + string LanguageCode = LanguageCodes[Index]; + + foreach (char Chr in LanguageCode) { - AMemoryHelper.WriteBytes(Context.Memory, Position += 8, BitConverter.GetBytes(value)); + Context.Memory.WriteByte(Position++, (byte)Chr); + } + + for (int Offs = 0; Offs < (8 - LanguageCode.Length); Offs++) + { + Context.Memory.WriteByte(Position++, 0); } } - Context.ResponseData.Write(LangCodesCount); + Context.ResponseData.Write(Count); return 0; } public static long GetAvailableLanguageCodeCount(ServiceCtx Context) { - Context.ResponseData.Write(LangCodesCount); + Context.ResponseData.Write(LanguageCodes.Length); return 0; } diff --git a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs index 3c1ed2159..c9e992d5d 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs @@ -156,7 +156,7 @@ namespace Ryujinx.Core.OsHle.Svc KSession Session = new KSession(ServiceFactory.MakeService(Name)); ulong Handle = (ulong)Process.HandleTable.OpenHandle(Session); - + ThreadState.X0 = 0; ThreadState.X1 = Handle; } @@ -268,7 +268,7 @@ namespace Ryujinx.Core.OsHle.Svc case 6: ThreadState.X1 = MemoryRegions.TotalMemoryAvailable; break; - + case 7: ThreadState.X1 = MemoryRegions.TotalMemoryUsed + CurrentHeapSize; break;