1
0
Fork 0
forked from Mirror/Ryujinx

irs: Stub some service calls ()

This PR stubs some irs service calls which are needed to get some games playable or at least bootable since we don't support IR data throught real JoyCon for now.

- Stubs `IIrSensorServer` `StopImageProcessor`, `RunMomentProcessor`, `RunClusteringProcessor`, `RunImageTransferProcessor`, `GetImageTransferProcessorState`, `RunTeraPluginProcessor`. All calls are a bit checked by RE.

Closes , , 

Night Vision and SpyAlarm are now bootable (but still unplayable due to the lack of the IR data):
This commit is contained in:
Ac_K 2021-09-29 00:10:10 +02:00 committed by GitHub
parent 83bdafccda
commit 79c854dd2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 233 additions and 2 deletions

View file

@ -1,7 +1,9 @@
using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Services.Hid.HidServer; using Ryujinx.HLE.HOS.Services.Hid.HidServer;
using Ryujinx.HLE.HOS.Services.Hid.Irs.Types;
using System; using System;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs namespace Ryujinx.HLE.HOS.Services.Hid.Irs
@ -17,7 +19,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
// ActivateIrsensor(nn::applet::AppletResourceUserId, pid) // ActivateIrsensor(nn::applet::AppletResourceUserId, pid)
public ResultCode ActivateIrsensor(ServiceCtx context) public ResultCode ActivateIrsensor(ServiceCtx context)
{ {
long appletResourceUserId = context.RequestData.ReadInt64(); ulong appletResourceUserId = context.RequestData.ReadUInt64();
// NOTE: This seems to initialize the shared memory for irs service.
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId }); Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId });
@ -28,7 +32,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
// DeactivateIrsensor(nn::applet::AppletResourceUserId, pid) // DeactivateIrsensor(nn::applet::AppletResourceUserId, pid)
public ResultCode DeactivateIrsensor(ServiceCtx context) public ResultCode DeactivateIrsensor(ServiceCtx context)
{ {
long appletResourceUserId = context.RequestData.ReadInt64(); ulong appletResourceUserId = context.RequestData.ReadUInt64();
// NOTE: This seems to deinitialize the shared memory for irs service.
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId }); Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId });
@ -39,6 +45,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
// GetIrsensorSharedMemoryHandle(nn::applet::AppletResourceUserId, pid) -> handle<copy> // GetIrsensorSharedMemoryHandle(nn::applet::AppletResourceUserId, pid) -> handle<copy>
public ResultCode GetIrsensorSharedMemoryHandle(ServiceCtx context) public ResultCode GetIrsensorSharedMemoryHandle(ServiceCtx context)
{ {
// NOTE: Shared memory should use the appletResourceUserId.
// ulong appletResourceUserId = context.RequestData.ReadUInt64();
if (_irsensorSharedMemoryHandle == 0) if (_irsensorSharedMemoryHandle == 0)
{ {
if (context.Process.HandleTable.GenerateHandle(context.Device.System.IirsSharedMem, out _irsensorSharedMemoryHandle) != KernelResult.Success) if (context.Process.HandleTable.GenerateHandle(context.Device.System.IirsSharedMem, out _irsensorSharedMemoryHandle) != KernelResult.Success)
@ -52,6 +61,111 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
return ResultCode.Success; return ResultCode.Success;
} }
[CommandHipc(305)]
// StopImageProcessor(pid, nn::irsensor::IrCameraHandle, nn::applet::AppletResourceUserId)
public ResultCode StopImageProcessor(ServiceCtx context)
{
IrCameraHandle irCameraHandle = context.RequestData.ReadStruct<IrCameraHandle>();
ulong appletResourceUserId = context.RequestData.ReadUInt64();
CheckCameraHandle(irCameraHandle);
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId, irCameraHandle.PlayerNumber, irCameraHandle.DeviceType });
return ResultCode.Success;
}
[CommandHipc(306)]
// RunMomentProcessor(pid, nn::irsensor::IrCameraHandle, nn::applet::AppletResourceUserId, PackedMomentProcessorConfig)
public ResultCode RunMomentProcessor(ServiceCtx context)
{
IrCameraHandle irCameraHandle = context.RequestData.ReadStruct<IrCameraHandle>();
ulong appletResourceUserId = context.RequestData.ReadUInt64();
var packedMomentProcessorConfig = context.RequestData.ReadStruct<PackedMomentProcessorConfig>();
CheckCameraHandle(irCameraHandle);
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId, irCameraHandle.PlayerNumber, irCameraHandle.DeviceType, packedMomentProcessorConfig.ExposureTime });
return ResultCode.Success;
}
[CommandHipc(307)]
// RunClusteringProcessor(pid, nn::irsensor::IrCameraHandle, nn::applet::AppletResourceUserId, PackedClusteringProcessorConfig)
public ResultCode RunClusteringProcessor(ServiceCtx context)
{
IrCameraHandle irCameraHandle = context.RequestData.ReadStruct<IrCameraHandle>();
ulong appletResourceUserId = context.RequestData.ReadUInt64();
var packedClusteringProcessorConfig = context.RequestData.ReadStruct<PackedClusteringProcessorConfig>();
CheckCameraHandle(irCameraHandle);
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId, irCameraHandle.PlayerNumber, irCameraHandle.DeviceType, packedClusteringProcessorConfig.ExposureTime });
return ResultCode.Success;
}
[CommandHipc(308)]
// RunImageTransferProcessor(pid, nn::irsensor::IrCameraHandle, nn::applet::AppletResourceUserId, PackedImageTransferProcessorConfig, u64 TransferMemorySize, TransferMemoryHandle)
public ResultCode RunImageTransferProcessor(ServiceCtx context)
{
IrCameraHandle irCameraHandle = context.RequestData.ReadStruct<IrCameraHandle>();
ulong appletResourceUserId = context.RequestData.ReadUInt64();
var packedImageTransferProcessorConfig = context.RequestData.ReadStruct<PackedImageTransferProcessorConfig>();
CheckCameraHandle(irCameraHandle);
// TODO: Handle the Transfer Memory.
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId, irCameraHandle.PlayerNumber, irCameraHandle.DeviceType, packedImageTransferProcessorConfig.ExposureTime });
return ResultCode.Success;
}
[CommandHipc(309)]
// GetImageTransferProcessorState(pid, nn::irsensor::IrCameraHandle, nn::applet::AppletResourceUserId)
public ResultCode GetImageTransferProcessorState(ServiceCtx context)
{
IrCameraHandle irCameraHandle = context.RequestData.ReadStruct<IrCameraHandle>();
ulong appletResourceUserId = context.RequestData.ReadUInt64();
// ulong imageTransferBufferAddress = context.Request.ReceiveBuff[0].Position;
ulong imageTransferBufferSize = context.Request.ReceiveBuff[0].Size;
if (imageTransferBufferSize == 0)
{
return ResultCode.InvalidBufferSize;
}
CheckCameraHandle(irCameraHandle);
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId, irCameraHandle.PlayerNumber, irCameraHandle.DeviceType });
// TODO: Uses the buffer to copy the JoyCon IR data (by using a JoyCon driver) and update the following struct.
context.ResponseData.WriteStruct(new ImageTransferProcessorState()
{
SamplingNumber = 0,
AmbientNoiseLevel = 0
});
return ResultCode.Success;
}
[CommandHipc(310)]
// RunTeraPluginProcessor(pid, nn::irsensor::IrCameraHandle, nn::applet::AppletResourceUserId, PackedTeraPluginProcessorConfig)
public ResultCode RunTeraPluginProcessor(ServiceCtx context)
{
IrCameraHandle irCameraHandle = context.RequestData.ReadStruct<IrCameraHandle>();
ulong appletResourceUserId = context.RequestData.ReadUInt64();
var packedTeraPluginProcessorConfig = context.RequestData.ReadStruct<PackedTeraPluginProcessorConfig>();
CheckCameraHandle(irCameraHandle);
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId, irCameraHandle.PlayerNumber, irCameraHandle.DeviceType, packedTeraPluginProcessorConfig.RequiredMcuVersion });
return ResultCode.Success;
}
[CommandHipc(311)] [CommandHipc(311)]
// GetNpadIrCameraHandle(u32) -> nn::irsensor::IrCameraHandle // GetNpadIrCameraHandle(u32) -> nn::irsensor::IrCameraHandle
public ResultCode GetNpadIrCameraHandle(ServiceCtx context) public ResultCode GetNpadIrCameraHandle(ServiceCtx context)
@ -100,5 +214,15 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
return ResultCode.Success; return ResultCode.Success;
} }
private ResultCode CheckCameraHandle(IrCameraHandle irCameraHandle)
{
if (irCameraHandle.DeviceType == 1 || (PlayerIndex)irCameraHandle.PlayerNumber >= PlayerIndex.Unknown)
{
return ResultCode.InvalidCameraHandle;
}
return ResultCode.Success;
}
} }
} }

View file

@ -7,6 +7,8 @@
Success = 0, Success = 0,
InvalidCameraHandle = (204 << ErrorCodeShift) | ModuleId,
InvalidBufferSize = (207 << ErrorCodeShift) | ModuleId,
HandlePointerIsNull = (212 << ErrorCodeShift) | ModuleId, HandlePointerIsNull = (212 << ErrorCodeShift) | ModuleId,
NpadIdOutOfRange = (709 << ErrorCodeShift) | ModuleId NpadIdOutOfRange = (709 << ErrorCodeShift) | ModuleId
} }

View file

@ -0,0 +1,12 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types
{
[StructLayout(LayoutKind.Sequential, Size = 0x10)]
struct ImageTransferProcessorState
{
public ulong SamplingNumber;
public uint AmbientNoiseLevel;
public uint Reserved;
}
}

View file

@ -0,0 +1,12 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types
{
[StructLayout(LayoutKind.Sequential, Size = 0x4)]
struct IrCameraHandle
{
public byte PlayerNumber;
public byte DeviceType;
public ushort Reserved;
}
}

View file

@ -0,0 +1,25 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types
{
[StructLayout(LayoutKind.Sequential, Size = 0x28)]
struct PackedClusteringProcessorConfig
{
public long ExposureTime;
public byte LightTarget;
public byte Gain;
public byte IsNegativeImageUsed;
public byte Reserved1;
public uint Reserved2;
public ushort WindowOfInterestX;
public ushort WindowOfInterestY;
public ushort WindowOfInterestWidth;
public ushort WindowOfInterestHeight;
public uint RequiredMcuVersion;
public uint ObjectPixelCountMin;
public uint ObjectPixelCountMax;
public byte ObjectIntensityMin;
public byte IsExternalLightFilterEnabled;
public ushort Reserved3;
}
}

View file

@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types
{
[StructLayout(LayoutKind.Sequential, Size = 0x18)]
struct PackedImageTransferProcessorConfig
{
public long ExposureTime;
public byte LightTarget;
public byte Gain;
public byte IsNegativeImageUsed;
public byte Reserved1;
public uint Reserved2;
public uint RequiredMcuVersion;
public byte Format;
public byte Reserved3;
public ushort Reserved4;
}
}

View file

@ -0,0 +1,23 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types
{
[StructLayout(LayoutKind.Sequential, Size = 0x20)]
struct PackedMomentProcessorConfig
{
public long ExposureTime;
public byte LightTarget;
public byte Gain;
public byte IsNegativeImageUsed;
public byte Reserved1;
public uint Reserved2;
public ushort WindowOfInterestX;
public ushort WindowOfInterestY;
public ushort WindowOfInterestWidth;
public ushort WindowOfInterestHeight;
public uint RequiredMcuVersion;
public byte Preprocess;
public byte PreprocessIntensityThreshold;
public ushort Reserved3;
}
}

View file

@ -0,0 +1,14 @@
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs.Types
{
[StructLayout(LayoutKind.Sequential, Size = 0x8)]
struct PackedTeraPluginProcessorConfig
{
public uint RequiredMcuVersion;
public byte Mode;
public byte Unknown1;
public byte Unknown2;
public byte Unknown3;
}
}