NvGetConfig with production/non production swapping (#243)
* GetConfig should return 0x30006 in production mode * GetConfig will now check settings only if nv!rmos_set_production_mode is set to "0" * Code formatting, TryGetValue * Slight fixup * dont forget the setting * Implemented non production mode setting grabbing * format issue * style changes
This commit is contained in:
parent
09c53fe06f
commit
37071285bc
2 changed files with 60 additions and 16 deletions
|
@ -2,6 +2,7 @@ using ChocolArm64.Memory;
|
||||||
using Ryujinx.HLE.Logging;
|
using Ryujinx.HLE.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl
|
namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl
|
||||||
|
@ -10,9 +11,16 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl
|
||||||
{
|
{
|
||||||
private static ConcurrentDictionary<Process, NvHostCtrlUserCtx> UserCtxs;
|
private static ConcurrentDictionary<Process, NvHostCtrlUserCtx> UserCtxs;
|
||||||
|
|
||||||
|
private static bool IsProductionMode = true;
|
||||||
|
|
||||||
static NvHostCtrlIoctl()
|
static NvHostCtrlIoctl()
|
||||||
{
|
{
|
||||||
UserCtxs = new ConcurrentDictionary<Process, NvHostCtrlUserCtx>();
|
UserCtxs = new ConcurrentDictionary<Process, NvHostCtrlUserCtx>();
|
||||||
|
|
||||||
|
if (Set.NxSettings.Settings.TryGetValue("nv!rmos_set_production_mode", out object ProductionModeSetting))
|
||||||
|
{
|
||||||
|
IsProductionMode = ((string)ProductionModeSetting) != "0"; // Default value is ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ProcessIoctl(ServiceCtx Context, int Cmd)
|
public static int ProcessIoctl(ServiceCtx Context, int Cmd)
|
||||||
|
@ -70,20 +78,55 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetConfig(ServiceCtx Context)
|
private static int GetConfig(ServiceCtx Context)
|
||||||
|
{
|
||||||
|
if (!IsProductionMode)
|
||||||
{
|
{
|
||||||
long InputPosition = Context.Request.GetBufferType0x21().Position;
|
long InputPosition = Context.Request.GetBufferType0x21().Position;
|
||||||
long OutputPosition = Context.Request.GetBufferType0x22().Position;
|
long OutputPosition = Context.Request.GetBufferType0x22().Position;
|
||||||
|
|
||||||
string Nv = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0, 0x41);
|
string Domain = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0, 0x41);
|
||||||
string Name = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0x41, 0x41);
|
string Name = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0x41, 0x41);
|
||||||
|
|
||||||
Context.Memory.WriteByte(OutputPosition + 0x82, 0);
|
if (Set.NxSettings.Settings.TryGetValue($"{Domain}!{Name}", out object NvSetting))
|
||||||
|
{
|
||||||
|
byte[] SettingBuffer = new byte[0x101];
|
||||||
|
|
||||||
Context.Ns.Log.PrintStub(LogClass.ServiceNv, "Stubbed.");
|
if (NvSetting is string StringValue)
|
||||||
|
{
|
||||||
|
if (StringValue.Length > 0x100)
|
||||||
|
{
|
||||||
|
Context.Ns.Log.PrintError(Logging.LogClass.ServiceNv, $"{Domain}!{Name} String value size is too big!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SettingBuffer = Encoding.ASCII.GetBytes(StringValue + "\0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NvSetting is int IntValue)
|
||||||
|
{
|
||||||
|
SettingBuffer = BitConverter.GetBytes(IntValue);
|
||||||
|
}
|
||||||
|
else if (NvSetting is bool BoolValue)
|
||||||
|
{
|
||||||
|
SettingBuffer[0] = BoolValue ? (byte)1 : (byte)0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException(NvSetting.GetType().Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context.Memory.WriteBytes(OutputPosition + 0x82, SettingBuffer);
|
||||||
|
|
||||||
|
Context.Ns.Log.PrintDebug(Logging.LogClass.ServiceNv, $"Got setting {Domain}!{Name}");
|
||||||
|
}
|
||||||
|
|
||||||
return NvResult.Success;
|
return NvResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NvResult.NotAvailableInProduction;
|
||||||
|
}
|
||||||
|
|
||||||
private static int EventWait(ServiceCtx Context)
|
private static int EventWait(ServiceCtx Context)
|
||||||
{
|
{
|
||||||
return EventWait(Context, Async: false);
|
return EventWait(Context, Async: false);
|
||||||
|
|
|
@ -2,6 +2,7 @@ namespace Ryujinx.HLE.OsHle.Services.Nv
|
||||||
{
|
{
|
||||||
static class NvResult
|
static class NvResult
|
||||||
{
|
{
|
||||||
|
public const int NotAvailableInProduction = 196614;
|
||||||
public const int Success = 0;
|
public const int Success = 0;
|
||||||
public const int TryAgain = -11;
|
public const int TryAgain = -11;
|
||||||
public const int OutOfMemory = -12;
|
public const int OutOfMemory = -12;
|
||||||
|
|
Reference in a new issue