More HidServer progress

This commit is contained in:
Isaac Marovitz 2024-07-20 16:53:29 +01:00
parent ca6a667853
commit 818467012c
No known key found for this signature in database
GPG key ID: 97250B2B09A132E1
8 changed files with 184 additions and 499 deletions

View file

@ -40,12 +40,5 @@ namespace Ryujinx.HLE.HOS.Services.Hid.HidServer
_ => throw new ArgumentOutOfRangeException(nameof(index)),
#pragma warning restore IDE0055
};
public static bool IsValidNpadIdType(NpadIdType npadIdType)
{
return (npadIdType >= NpadIdType.Player1 && npadIdType <= NpadIdType.Player8) ||
npadIdType == NpadIdType.Handheld ||
npadIdType == NpadIdType.Unknown;
}
}
}

View file

@ -76,19 +76,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(32)]
// SendKeyboardLockKeyEvent(uint flags, pid)
public ResultCode SendKeyboardLockKeyEvent(ServiceCtx context)
{
uint flags = context.RequestData.ReadUInt32();
// NOTE: This signal the keyboard driver about lock events.
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { flags });
return ResultCode.Success;
}
[CommandCmif(40)]
// AcquireXpadIdEventHandle(ulong XpadId) -> nn::sf::NativeHandle
public ResultCode AcquireXpadIdEventHandle(ServiceCtx context)
@ -120,29 +107,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(55)]
// GetXpadIds() -> long IdsCount, buffer<array<nn::hid::BasicXpadId>, type: 0xa>
public ResultCode GetXpadIds(ServiceCtx context)
{
// There is any Xpad, so we return 0 and write nothing inside the type-0xa buffer.
context.ResponseData.Write(0L);
Logger.Stub?.PrintStub(LogClass.ServiceHid);
return ResultCode.Success;
}
[CommandCmif(56)]
// ActivateJoyXpad(nn::hid::JoyXpadId)
public ResultCode ActivateJoyXpad(ServiceCtx context)
{
int joyXpadId = context.RequestData.ReadInt32();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
return ResultCode.Success;
}
[CommandCmif(58)]
// GetJoyXpadLifoHandle(nn::hid::JoyXpadId) -> nn::sf::NativeHandle
public ResultCode GetJoyXpadLifoHandle(ServiceCtx context)
@ -158,40 +122,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(59)]
// GetJoyXpadIds() -> long IdsCount, buffer<array<nn::hid::JoyXpadId>, type: 0xa>
public ResultCode GetJoyXpadIds(ServiceCtx context)
{
// There is any JoyXpad, so we return 0 and write nothing inside the type-0xa buffer.
context.ResponseData.Write(0L);
Logger.Stub?.PrintStub(LogClass.ServiceHid);
return ResultCode.Success;
}
[CommandCmif(60)]
// ActivateSixAxisSensor(nn::hid::BasicXpadId)
public ResultCode ActivateSixAxisSensor(ServiceCtx context)
{
int basicXpadId = context.RequestData.ReadInt32();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
return ResultCode.Success;
}
[CommandCmif(61)]
// DeactivateSixAxisSensor(nn::hid::BasicXpadId)
public ResultCode DeactivateSixAxisSensor(ServiceCtx context)
{
int basicXpadId = context.RequestData.ReadInt32();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
return ResultCode.Success;
}
[CommandCmif(62)]
// GetSixAxisSensorLifoHandle(nn::hid::BasicXpadId) -> nn::sf::NativeHandle
public ResultCode GetSixAxisSensorLifoHandle(ServiceCtx context)
@ -207,28 +137,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(63)]
// ActivateJoySixAxisSensor(nn::hid::JoyXpadId)
public ResultCode ActivateJoySixAxisSensor(ServiceCtx context)
{
int joyXpadId = context.RequestData.ReadInt32();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
return ResultCode.Success;
}
[CommandCmif(64)]
// DeactivateJoySixAxisSensor(nn::hid::JoyXpadId)
public ResultCode DeactivateJoySixAxisSensor(ServiceCtx context)
{
int joyXpadId = context.RequestData.ReadInt32();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
return ResultCode.Success;
}
[CommandCmif(65)]
// GetJoySixAxisSensorLifoHandle(nn::hid::JoyXpadId) -> nn::sf::NativeHandle
public ResultCode GetJoySixAxisSensorLifoHandle(ServiceCtx context)
@ -244,144 +152,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(66)]
// StartSixAxisSensor(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public ResultCode StartSixAxisSensor(ServiceCtx context)
{
int sixAxisSensorHandle = context.RequestData.ReadInt32();
context.RequestData.BaseStream.Position += 4; // Padding
long appletResourceUserId = context.RequestData.ReadInt64();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle });
return ResultCode.Success;
}
[CommandCmif(67)]
// StopSixAxisSensor(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public ResultCode StopSixAxisSensor(ServiceCtx context)
{
int sixAxisSensorHandle = context.RequestData.ReadInt32();
context.RequestData.BaseStream.Position += 4; // Padding
long appletResourceUserId = context.RequestData.ReadInt64();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle });
return ResultCode.Success;
}
[CommandCmif(68)]
// IsSixAxisSensorFusionEnabled(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsEnabled
public ResultCode IsSixAxisSensorFusionEnabled(ServiceCtx context)
{
int sixAxisSensorHandle = context.RequestData.ReadInt32();
context.RequestData.BaseStream.Position += 4; // Padding
long appletResourceUserId = context.RequestData.ReadInt64();
context.ResponseData.Write(_sixAxisSensorFusionEnabled);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sixAxisSensorFusionEnabled });
return ResultCode.Success;
}
[CommandCmif(69)]
// EnableSixAxisSensorFusion(bool Enabled, nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public ResultCode EnableSixAxisSensorFusion(ServiceCtx context)
{
_sixAxisSensorFusionEnabled = context.RequestData.ReadUInt32() != 0;
int sixAxisSensorHandle = context.RequestData.ReadInt32();
long appletResourceUserId = context.RequestData.ReadInt64();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sixAxisSensorFusionEnabled });
return ResultCode.Success;
}
[CommandCmif(70)]
// SetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, float RevisePower, float ReviseRange, nn::applet::AppletResourceUserId)
public ResultCode SetSixAxisSensorFusionParameters(ServiceCtx context)
{
int sixAxisSensorHandle = context.RequestData.ReadInt32();
context.RequestData.BaseStream.Position += 4; // Padding
_sensorFusionParams = new SensorFusionParameters
{
RevisePower = context.RequestData.ReadInt32(),
ReviseRange = context.RequestData.ReadInt32(),
};
long appletResourceUserId = context.RequestData.ReadInt64();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
return ResultCode.Success;
}
[CommandCmif(71)]
// GetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> float RevisePower, float ReviseRange)
public ResultCode GetSixAxisSensorFusionParameters(ServiceCtx context)
{
int sixAxisSensorHandle = context.RequestData.ReadInt32();
context.RequestData.BaseStream.Position += 4; // Padding
long appletResourceUserId = context.RequestData.ReadInt64();
context.ResponseData.Write(_sensorFusionParams.RevisePower);
context.ResponseData.Write(_sensorFusionParams.ReviseRange);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
return ResultCode.Success;
}
[CommandCmif(72)]
// ResetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
public ResultCode ResetSixAxisSensorFusionParameters(ServiceCtx context)
{
int sixAxisSensorHandle = context.RequestData.ReadInt32();
context.RequestData.BaseStream.Position += 4; // Padding
long appletResourceUserId = context.RequestData.ReadInt64();
_sensorFusionParams.RevisePower = 0;
_sensorFusionParams.ReviseRange = 0;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
return ResultCode.Success;
}
[CommandCmif(82)]
// IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAsRest
public ResultCode IsSixAxisSensorAtRest(ServiceCtx context)
{
int sixAxisSensorHandle = context.RequestData.ReadInt32();
context.RequestData.BaseStream.Position += 4; // Padding
long appletResourceUserId = context.RequestData.ReadInt64();
bool isAtRest = true;
context.ResponseData.Write(isAtRest);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, isAtRest });
return ResultCode.Success;
}
[CommandCmif(83)] // 6.0.0+
// IsFirmwareUpdateAvailableForSixAxisSensor(nn::hid::AppletResourceUserId, nn::hid::SixAxisSensorHandle, pid) -> bool UpdateAvailable
public ResultCode IsFirmwareUpdateAvailableForSixAxisSensor(ServiceCtx context)
{
int sixAxisSensorHandle = context.RequestData.ReadInt32();
context.RequestData.BaseStream.Position += 4; // Padding
long appletResourceUserId = context.RequestData.ReadInt64();
context.ResponseData.Write(_isFirmwareUpdateAvailableForSixAxisSensor);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _isFirmwareUpdateAvailableForSixAxisSensor });
return ResultCode.Success;
}
[CommandCmif(84)] // 13.0.0+
// EnableSixAxisSensorUnalteredPassthrough(nn::applet::AppletResourceUserId, nn::hid::SixAxisSensorHandle, u8 enabled)
public ResultCode EnableSixAxisSensorUnalteredPassthrough(ServiceCtx context)
@ -816,129 +586,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(200)]
// GetVibrationDeviceInfo(nn::hid::VibrationDeviceHandle) -> nn::hid::VibrationDeviceInfo
public ResultCode GetVibrationDeviceInfo(ServiceCtx context)
{
VibrationDeviceHandle deviceHandle = context.RequestData.ReadStruct<VibrationDeviceHandle>();
NpadStyleIndex deviceType = (NpadStyleIndex)deviceHandle.DeviceType;
NpadIdType npadIdType = (NpadIdType)deviceHandle.PlayerId;
if (deviceType < NpadStyleIndex.System || deviceType >= NpadStyleIndex.FullKey)
{
if (!HidUtils.IsValidNpadIdType(npadIdType))
{
return ResultCode.InvalidNpadIdType;
}
if (deviceHandle.Position > 1)
{
return ResultCode.InvalidDeviceIndex;
}
VibrationDeviceType vibrationDeviceType = VibrationDeviceType.None;
if (Enum.IsDefined(deviceType))
{
vibrationDeviceType = VibrationDeviceType.LinearResonantActuator;
}
else if ((uint)deviceType == 8)
{
vibrationDeviceType = VibrationDeviceType.GcErm;
}
VibrationDevicePosition vibrationDevicePosition = VibrationDevicePosition.None;
if (vibrationDeviceType == VibrationDeviceType.LinearResonantActuator)
{
if (deviceHandle.Position == 0)
{
vibrationDevicePosition = VibrationDevicePosition.Left;
}
else if (deviceHandle.Position == 1)
{
vibrationDevicePosition = VibrationDevicePosition.Right;
}
else
{
throw new InvalidOperationException($"{nameof(deviceHandle.Position)} contains an invalid value: {deviceHandle.Position}");
}
}
VibrationDeviceValue deviceInfo = new()
{
DeviceType = vibrationDeviceType,
Position = vibrationDevicePosition,
};
context.ResponseData.WriteStruct(deviceInfo);
return ResultCode.Success;
}
return ResultCode.InvalidNpadDeviceType;
}
[CommandCmif(201)]
// SendVibrationValue(nn::hid::VibrationDeviceHandle, nn::hid::VibrationValue, nn::applet::AppletResourceUserId)
public ResultCode SendVibrationValue(ServiceCtx context)
{
VibrationDeviceHandle deviceHandle = new()
{
DeviceType = context.RequestData.ReadByte(),
PlayerId = context.RequestData.ReadByte(),
Position = context.RequestData.ReadByte(),
Reserved = context.RequestData.ReadByte(),
};
VibrationValue vibrationValue = new()
{
AmplitudeLow = context.RequestData.ReadSingle(),
FrequencyLow = context.RequestData.ReadSingle(),
AmplitudeHigh = context.RequestData.ReadSingle(),
FrequencyHigh = context.RequestData.ReadSingle(),
};
#pragma warning disable IDE0059 // Remove unnecessary value assignment
long appletResourceUserId = context.RequestData.ReadInt64();
#pragma warning restore IDE0059
Dictionary<byte, VibrationValue> dualVibrationValues = new()
{
[deviceHandle.Position] = vibrationValue,
};
context.Device.Hid.Npads.UpdateRumbleQueue((PlayerIndex)deviceHandle.PlayerId, dualVibrationValues);
return ResultCode.Success;
}
[CommandCmif(202)]
// GetActualVibrationValue(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationValue
public ResultCode GetActualVibrationValue(ServiceCtx context)
{
VibrationDeviceHandle deviceHandle = new()
{
DeviceType = context.RequestData.ReadByte(),
PlayerId = context.RequestData.ReadByte(),
Position = context.RequestData.ReadByte(),
Reserved = context.RequestData.ReadByte(),
};
#pragma warning disable IDE0059 // Remove unnecessary value assignment
long appletResourceUserId = context.RequestData.ReadInt64();
#pragma warning restore IDE0059
VibrationValue vibrationValue = context.Device.Hid.Npads.GetLastVibrationValue((PlayerIndex)deviceHandle.PlayerId, deviceHandle.Position);
context.ResponseData.Write(vibrationValue.AmplitudeLow);
context.ResponseData.Write(vibrationValue.FrequencyLow);
context.ResponseData.Write(vibrationValue.AmplitudeHigh);
context.ResponseData.Write(vibrationValue.FrequencyHigh);
return ResultCode.Success;
}
[CommandCmif(203)]
// CreateActiveVibrationDeviceList() -> object<nn::hid::IActiveVibrationDeviceList>
public ResultCode CreateActiveVibrationDeviceList(ServiceCtx context)
@ -948,26 +595,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(204)]
// PermitVibration(bool Enable)
public ResultCode PermitVibration(ServiceCtx context)
{
_vibrationPermitted = context.RequestData.ReadBoolean();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _vibrationPermitted });
return ResultCode.Success;
}
[CommandCmif(205)]
// IsVibrationPermitted() -> bool IsEnabled
public ResultCode IsVibrationPermitted(ServiceCtx context)
{
context.ResponseData.Write(_vibrationPermitted);
return ResultCode.Success;
}
[CommandCmif(206)]
// SendVibrationValues(nn::applet::AppletResourceUserId, buffer<array<nn::hid::VibrationDeviceHandle>, type: 9>, buffer<array<nn::hid::VibrationValue>, type: 9>)
public ResultCode SendVibrationValues(ServiceCtx context)
@ -1013,47 +640,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(207)] // 4.0.0+
// SendVibrationGcErmCommand(nn::hid::VibrationDeviceHandle, nn::hid::VibrationGcErmCommand, nn::applet::AppletResourceUserId)
public ResultCode SendVibrationGcErmCommand(ServiceCtx context)
{
int vibrationDeviceHandle = context.RequestData.ReadInt32();
long vibrationGcErmCommand = context.RequestData.ReadInt64();
long appletResourceUserId = context.RequestData.ReadInt64();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, vibrationDeviceHandle, vibrationGcErmCommand });
return ResultCode.Success;
}
[CommandCmif(208)] // 4.0.0+
// GetActualVibrationGcErmCommand(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationGcErmCommand
public ResultCode GetActualVibrationGcErmCommand(ServiceCtx context)
{
int vibrationDeviceHandle = context.RequestData.ReadInt32();
long appletResourceUserId = context.RequestData.ReadInt64();
context.ResponseData.Write(_vibrationGcErmCommand);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, vibrationDeviceHandle, _vibrationGcErmCommand });
return ResultCode.Success;
}
[CommandCmif(406)] // 4.0.0+
// GetNpadLeftRightInterfaceType(uint NpadId) -> uchar LeftInterfaceType, uchar RightInterfaceType
public ResultCode GetNpadLeftRightInterfaceType(ServiceCtx context)
{
int npadId = context.RequestData.ReadInt32();
context.ResponseData.Write((byte)0);
context.ResponseData.Write((byte)0);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, LeftInterfaceType = 0, RightInterfaceType = 0 });
return ResultCode.Success;
}
[CommandCmif(500)] // 5.0.0+
// GetPalmaConnectionHandle(uint Unknown0, nn::applet::AppletResourceUserId) -> nn::hid::PalmaConnectionHandle
public ResultCode GetPalmaConnectionHandle(ServiceCtx context)

View file

@ -0,0 +1,14 @@
using Ryujinx.Horizon.Common;
namespace Ryujinx.Horizon.Hid
{
class HidResult
{
private const int ModuleId = 202;
public static Result InvalidNpadDeviceType => new Result(ModuleId, 122);
public static Result InvalidNpadIdType => new Result(ModuleId, 123);
public static Result InvalidDeviceIndex => new Result(ModuleId, 124);
public static Result InvalidBufferSize => new Result(ModuleId, 131);
}
}

View file

@ -9,6 +9,7 @@ using Ryujinx.Horizon.Sdk.Hid.Vibration;
using Ryujinx.Horizon.Sdk.Sf;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using System;
using System.Collections.Generic;
namespace Ryujinx.Horizon.Hid
{
@ -35,6 +36,7 @@ namespace Ryujinx.Horizon.Hid
private long _npadCommunicationMode;
private uint _accelerometerPlayMode;
private readonly VibrationGcErmCommand _vibrationGcErmCommand;
private float _sevenSixAxisSensorFusionStrength;
private SensorFusionParameters _sensorFusionParams;
@ -151,7 +153,7 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(40)]
public Result AcquireXpadIdEventHandle([CopyHandle] out int arg0, ulong xpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { xpadId });
return Result.Success;
}
@ -159,7 +161,7 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(41)]
public Result ReleaseXpadIdEventHandle(ulong xpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { xpadId });
return Result.Success;
}
@ -186,7 +188,7 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(56)]
public Result ActivateJoyXpad(uint joyXpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
return Result.Success;
}
@ -194,39 +196,42 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(58)]
public Result GetJoyXpadLifoHandle([CopyHandle] out int arg0, uint joyXpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
return Result.Success;
}
[CmifCommand(59)]
public Result GetJoyXpadIds(out long arg0, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer)] Span<uint> joyXpadIds)
public Result GetJoyXpadIds(out long idCount, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.Pointer)] Span<uint> joyXpadIds)
{
// There aren't any JoyXpad, so we return 0 and write nothing inside the buffer.
idCount = 0;
Logger.Stub?.PrintStub(LogClass.ServiceHid);
return Result.Success;
}
[CmifCommand(60)]
public Result ActivateSixAxisSensor(uint basixXpadId)
public Result ActivateSixAxisSensor(uint basicXpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
return Result.Success;
}
[CmifCommand(61)]
public Result DeactivateSixAxisSensor(uint basixXpadId)
public Result DeactivateSixAxisSensor(uint basicXpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
return Result.Success;
}
[CmifCommand(62)]
public Result GetSixAxisSensorLifoHandle([CopyHandle] out int arg0, uint basixXpadId)
public Result GetSixAxisSensorLifoHandle([CopyHandle] out int arg0, uint basicXpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
return Result.Success;
}
@ -234,7 +239,7 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(63)]
public Result ActivateJoySixAxisSensor(uint joyXpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
return Result.Success;
}
@ -242,7 +247,7 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(64)]
public Result DeactivateJoySixAxisSensor(uint joyXpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
return Result.Success;
}
@ -250,7 +255,7 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(65)]
public Result GetJoySixAxisSensorLifoHandle([CopyHandle] out int arg0, uint joyXpadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
return Result.Success;
}
@ -258,7 +263,7 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(66)]
public Result StartSixAxisSensor(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle });
return Result.Success;
}
@ -266,39 +271,52 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(67)]
public Result StopSixAxisSensor(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle });
return Result.Success;
}
[CmifCommand(68)]
public Result IsSixAxisSensorFusionEnabled(out bool arg0, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
public Result IsSixAxisSensorFusionEnabled(out bool sixAxisSensorFusionEnabled, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
sixAxisSensorFusionEnabled = _sixAxisSensorFusionEnabled;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sixAxisSensorFusionEnabled });
return Result.Success;
}
[CmifCommand(69)]
public Result EnableSixAxisSensorFusion(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, bool arg2, [ClientProcessId] ulong pid)
public Result EnableSixAxisSensorFusion(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, bool sixAxisSensorFusionEnabled, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
_sixAxisSensorFusionEnabled = sixAxisSensorFusionEnabled;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sixAxisSensorFusionEnabled });
return Result.Success;
}
[CmifCommand(70)]
public Result SetSixAxisSensorFusionParameters(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, float arg2, float arg3, [ClientProcessId] ulong pid)
public Result SetSixAxisSensorFusionParameters(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, float revisePower, float reviseRange, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
_sensorFusionParams = new SensorFusionParameters
{
RevisePower = revisePower,
ReviseRange = reviseRange
};
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
return Result.Success;
}
[CmifCommand(71)]
public Result GetSixAxisSensorFusionParameters(out float arg0, out float arg1, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
public Result GetSixAxisSensorFusionParameters(out float revisePower, out float reviseRange, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
revisePower = _sensorFusionParams.RevisePower;
reviseRange = _sensorFusionParams.ReviseRange;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
return Result.Success;
}
@ -306,7 +324,10 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(72)]
public Result ResetSixAxisSensorFusionParameters(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
_sensorFusionParams.RevisePower = 0;
_sensorFusionParams.ReviseRange = 0;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
return Result.Success;
}
@ -408,17 +429,21 @@ namespace Ryujinx.Horizon.Hid
}
[CmifCommand(82)]
public Result IsSixAxisSensorAtRest(out bool arg0, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
public Result IsSixAxisSensorAtRest(out bool isAtRest, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
isAtRest = true;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, isAtRest });
return Result.Success;
}
[CmifCommand(83)]
public Result IsFirmwareUpdateAvailableForSixAxisSensor(out bool arg0, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
public Result IsFirmwareUpdateAvailableForSixAxisSensor(out bool isFirmwareUpdateAvailableForSixAxisSensor, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
isFirmwareUpdateAvailableForSixAxisSensor = _isFirmwareUpdateAvailableForSixAxisSensor;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _isFirmwareUpdateAvailableForSixAxisSensor });
return Result.Success;
}
@ -698,23 +723,80 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(200)]
public Result GetVibrationDeviceInfo(out VibrationDeviceInfoForIpc vibrationDeviceInfoForIpc, VibrationDeviceHandle vibrationDeviceHandle)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
NpadStyleIndex deviceType = vibrationDeviceHandle.DeviceType;
NpadIdType npadIdType = vibrationDeviceHandle.PlayerId;
vibrationDeviceInfoForIpc = new();
if (deviceType < NpadStyleIndex.System || deviceType >= NpadStyleIndex.FullKey)
{
if (!IsValidNpadIdType(npadIdType))
{
return HidResult.InvalidNpadIdType;
}
if (vibrationDeviceHandle.Position > 1)
{
return HidResult.InvalidDeviceIndex;
}
VibrationDeviceType vibrationDeviceType = VibrationDeviceType.None;
if (Enum.IsDefined(deviceType))
{
vibrationDeviceType = VibrationDeviceType.LinearResonantActuator;
}
else if ((uint)deviceType == 8)
{
vibrationDeviceType = VibrationDeviceType.GcErm;
}
VibrationDevicePosition vibrationDevicePosition = VibrationDevicePosition.None;
if (vibrationDeviceType == VibrationDeviceType.LinearResonantActuator)
{
if (vibrationDeviceHandle.Position == 0)
{
vibrationDevicePosition = VibrationDevicePosition.Left;
}
else if (vibrationDeviceHandle.Position == 1)
{
vibrationDevicePosition = VibrationDevicePosition.Right;
}
else
{
throw new InvalidOperationException($"{nameof(vibrationDeviceHandle.Position)} contains an invalid value: {vibrationDeviceHandle.Position}");
}
}
vibrationDeviceInfoForIpc = new()
{
DeviceType = vibrationDeviceType,
Position = vibrationDevicePosition,
};
return Result.Success;
}
return HidResult.InvalidNpadDeviceType;
}
[CmifCommand(201)]
public Result SendVibrationValue(AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, VibrationValue arg2, [ClientProcessId] ulong pid)
public Result SendVibrationValue(AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, VibrationValue vibrationValue, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Dictionary<byte, VibrationValue> dualVibrationValues = new()
{
[vibrationDeviceHandle.Position] = vibrationValue,
};
Npads.UpdateRumbleQueue(vibrationDeviceHandle.PlayerId, dualVibrationValues);
return Result.Success;
}
[CmifCommand(202)]
public Result GetActualVibrationValue(out VibrationValue arg0, AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, [ClientProcessId] ulong pid)
public Result GetActualVibrationValue(out VibrationValue vibrationValue, AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
vibrationValue = Npads.GetLastVibrationValue(vibrationDeviceHandle.PlayerId, vibrationDeviceHandle.Position);
return Result.Success;
}
@ -728,17 +810,19 @@ namespace Ryujinx.Horizon.Hid
}
[CmifCommand(204)]
public Result PermitVibration(bool arg0)
public Result PermitVibration(bool vibrationPermitted)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
_vibrationPermitted = vibrationPermitted;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _vibrationPermitted });
return Result.Success;
}
[CmifCommand(205)]
public Result IsVibrationPermitted(out bool arg0)
public Result IsVibrationPermitted(out bool vibrationPermitted)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
vibrationPermitted = _vibrationPermitted;
return Result.Success;
}
@ -754,7 +838,7 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(207)]
public Result SendVibrationGcErmCommand(AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, VibrationGcErmCommand vibrationGcErmCommand, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, vibrationDeviceHandle, vibrationGcErmCommand });
return Result.Success;
}
@ -762,7 +846,9 @@ namespace Ryujinx.Horizon.Hid
[CmifCommand(208)]
public Result GetActualVibrationGcErmCommand(out VibrationGcErmCommand vibrationGcErmCommand, AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
vibrationGcErmCommand = _vibrationGcErmCommand;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, vibrationDeviceHandle, _vibrationGcErmCommand });
return Result.Success;
}
@ -958,15 +1044,18 @@ namespace Ryujinx.Horizon.Hid
}
[CmifCommand(406)]
public Result GetNpadLeftRightInterfaceType(out byte arg0, out byte arg1, uint arg2)
public Result GetNpadLeftRightInterfaceType(out byte leftInterfaceType, out byte rightInterfaceType, uint npadId)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
leftInterfaceType = 0;
rightInterfaceType = 0;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, LeftInterfaceType = 0, RightInterfaceType = 0 });
return Result.Success;
}
[CmifCommand(407)]
public Result GetNpadOfHighestBatteryLevel(out uint arg0, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<uint> arg1, AppletResourceUserId appletResourceUserId, [ClientProcessId] ulong pid)
public Result GetNpadOfHighestBatteryLevel(out uint npadId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<uint> arg1, AppletResourceUserId appletResourceUserId, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
@ -1242,9 +1331,11 @@ namespace Ryujinx.Horizon.Hid
}
[CmifCommand(1003)]
public Result IsFirmwareUpdateNeededForNotification(out bool arg0, int arg1, AppletResourceUserId appletResourceUserId, [ClientProcessId] ulong pid)
public Result IsFirmwareUpdateNeededForNotification(out bool isFirmwareUpdateNeededForNotification, int unknown, AppletResourceUserId appletResourceUserId, [ClientProcessId] ulong pid)
{
Logger.Stub?.PrintStub(LogClass.ServiceHid);
isFirmwareUpdateNeededForNotification = false;
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { IsFirmwareUpdateNeededForNotification = false, unknown, appletResourceUserId });
return Result.Success;
}
@ -1256,5 +1347,12 @@ namespace Ryujinx.Horizon.Hid
return Result.Success;
}
private static bool IsValidNpadIdType(NpadIdType npadIdType)
{
return (npadIdType >= NpadIdType.Player1 && npadIdType <= NpadIdType.Player8) ||
npadIdType == NpadIdType.Handheld ||
npadIdType == NpadIdType.Unknown;
}
}
}

View file

@ -33,8 +33,8 @@ namespace Ryujinx.Horizon.Sdk.Hid.HidDevices
internal bool SixAxisActive = false; // TODO: link to hidserver when implemented
internal NpadStyleTag SupportedStyleSets { get; set; }
public Dictionary<PlayerIndex, ConcurrentQueue<(VibrationValue, VibrationValue)>> RumbleQueues = new();
public Dictionary<PlayerIndex, (VibrationValue, VibrationValue)> LastVibrationValues = new();
public Dictionary<NpadIdType, ConcurrentQueue<(VibrationValue, VibrationValue)>> RumbleQueues = new();
public Dictionary<NpadIdType, (VibrationValue, VibrationValue)> LastVibrationValues = new();
public NpadDevices(bool active = true) : base(active)
{
@ -596,7 +596,7 @@ namespace Ryujinx.Horizon.Sdk.Hid.HidDevices
WriteNewSixInputEntry(ref currentNpad.JoyRightSixAxisSensor, ref newState);
}
public void UpdateRumbleQueue(PlayerIndex index, Dictionary<byte, VibrationValue> dualVibrationValues)
public void UpdateRumbleQueue(NpadIdType index, Dictionary<byte, VibrationValue> dualVibrationValues)
{
if (RumbleQueues.TryGetValue(index, out ConcurrentQueue<(VibrationValue, VibrationValue)> currentQueue))
{
@ -619,7 +619,7 @@ namespace Ryujinx.Horizon.Sdk.Hid.HidDevices
}
}
public VibrationValue GetLastVibrationValue(PlayerIndex index, byte position)
public VibrationValue GetLastVibrationValue(NpadIdType index, byte position)
{
if (!LastVibrationValues.TryGetValue(index, out (VibrationValue, VibrationValue) dualVibrationValue))
{
@ -629,7 +629,7 @@ namespace Ryujinx.Horizon.Sdk.Hid.HidDevices
return (position == 0) ? dualVibrationValue.Item1 : dualVibrationValue.Item2;
}
public ConcurrentQueue<(VibrationValue, VibrationValue)> GetRumbleQueue(PlayerIndex index)
public ConcurrentQueue<(VibrationValue, VibrationValue)> GetRumbleQueue(NpadIdType index)
{
if (!RumbleQueues.TryGetValue(index, out ConcurrentQueue<(VibrationValue, VibrationValue)> rumbleQueue))
{

View file

@ -21,19 +21,19 @@ namespace Ryujinx.Horizon.Sdk.Hid
Result GetXpadIds(out long idCount, Span<uint> basicXpadIds);
Result ActivateJoyXpad(uint joyXpadId);
Result GetJoyXpadLifoHandle(out int arg0, uint joyXpadId);
Result GetJoyXpadIds(out long arg0, Span<uint> joyXpadIds);
Result ActivateSixAxisSensor(uint basixXpadId);
Result DeactivateSixAxisSensor(uint basixXpadId);
Result GetSixAxisSensorLifoHandle(out int arg0, uint basixXpadId);
Result GetJoyXpadIds(out long idCount, Span<uint> joyXpadIds);
Result ActivateSixAxisSensor(uint basicXpadId);
Result DeactivateSixAxisSensor(uint basicXpadId);
Result GetSixAxisSensorLifoHandle(out int arg0, uint basicXpadId);
Result ActivateJoySixAxisSensor(uint joyXpadId);
Result DeactivateJoySixAxisSensor(uint joyXpadId);
Result GetJoySixAxisSensorLifoHandle(out int arg0, uint joyXpadId);
Result StartSixAxisSensor(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result StopSixAxisSensor(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result IsSixAxisSensorFusionEnabled(out bool arg0, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result EnableSixAxisSensorFusion(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, bool arg2, ulong pid);
Result SetSixAxisSensorFusionParameters(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, float arg2, float arg3, ulong pid);
Result GetSixAxisSensorFusionParameters(out float arg0, out float arg1, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result IsSixAxisSensorFusionEnabled(out bool sixAxisSensorFusionEnabled, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result EnableSixAxisSensorFusion(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, bool sixAxisSensorFusionEnabled, ulong pid);
Result SetSixAxisSensorFusionParameters(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, float revisePower, float reviseRange, ulong pid);
Result GetSixAxisSensorFusionParameters(out float revisePower, out float reviseRange, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result ResetSixAxisSensorFusionParameters(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result SetAccelerometerParameters(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, float x, float y, ulong pid);
Result GetAccelerometerParameters(out float x, out float y, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
@ -44,8 +44,8 @@ namespace Ryujinx.Horizon.Sdk.Hid
Result SetGyroscopeZeroDriftMode(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, GyroscopeZeroDriftMode gyroscopeZeroDriftMode, ulong pid);
Result GetGyroscopeZeroDriftMode(out GyroscopeZeroDriftMode gyroscopeZeroDriftMode, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result ResetGyroscopeZeroDriftMode(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result IsSixAxisSensorAtRest(out bool arg0, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result IsFirmwareUpdateAvailableForSixAxisSensor(out bool arg0, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result IsSixAxisSensorAtRest(out bool isAtRest, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result IsFirmwareUpdateAvailableForSixAxisSensor(out bool isFirmwareUpdateAvailableForSixAxisSensor, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result EnableSixAxisSensorUnalteredPassthrough(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, bool arg2, ulong pid);
Result IsSixAxisSensorUnalteredPassthroughEnabled(out bool arg0, AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, ulong pid);
Result StoreSixAxisSensorCalibrationParameter(AppletResourceUserId appletResourceUserId, SixAxisSensorHandle sixAxisSensorHandle, in SixAxisSensorCalibrationParameter sixAxisSensorCalibrationParameter, ulong pid);
@ -80,11 +80,11 @@ namespace Ryujinx.Horizon.Sdk.Hid
Result SetNpadCaptureButtonAssignment(AppletResourceUserId appletResourceUserId, NpadStyleTag arg1, NpadButton arg2, ulong pid);
Result ClearNpadCaptureButtonAssignment(AppletResourceUserId appletResourceUserId, ulong pid);
Result GetVibrationDeviceInfo(out VibrationDeviceInfoForIpc vibrationDeviceInfoForIpc, VibrationDeviceHandle vibrationDeviceHandle);
Result SendVibrationValue(AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, VibrationValue arg2, ulong pid);
Result GetActualVibrationValue(out VibrationValue arg0, AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, ulong pid);
Result SendVibrationValue(AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, VibrationValue vibrationValue, ulong pid);
Result GetActualVibrationValue(out VibrationValue vibrationValue, AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, ulong pid);
Result CreateActiveVibrationDeviceList(out IActiveVibrationDeviceList arg0);
Result PermitVibration(bool arg0);
Result IsVibrationPermitted(out bool arg0);
Result PermitVibration(bool vibrationPermitted);
Result IsVibrationPermitted(out bool vibrationPermitted);
Result SendVibrationValues(AppletResourceUserId appletResourceUserId, ReadOnlySpan<VibrationDeviceHandle> vibrationDeviceHandles, ReadOnlySpan<VibrationValue> vibrationValues);
Result SendVibrationGcErmCommand(AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, VibrationGcErmCommand vibrationGcErmCommand, ulong pid);
Result GetActualVibrationGcErmCommand(out VibrationGcErmCommand vibrationGcErmCommand, AppletResourceUserId appletResourceUserId, VibrationDeviceHandle vibrationDeviceHandle, ulong pid);
@ -109,8 +109,8 @@ namespace Ryujinx.Horizon.Sdk.Hid
Result HasBattery(out bool hasBattery, uint npadId);
Result HasLeftRightBattery(out bool hasLeftBattery, out bool hasRightBattery, uint npadId);
Result GetNpadInterfaceType(out byte npadInterfaceType, uint npadId);
Result GetNpadLeftRightInterfaceType(out byte arg0, out byte arg1, uint arg2);
Result GetNpadOfHighestBatteryLevel(out uint arg0, ReadOnlySpan<uint> arg1, AppletResourceUserId appletResourceUserId, ulong pid);
Result GetNpadLeftRightInterfaceType(out byte leftInterfaceType, out byte rightInterfaceType, uint npadId);
Result GetNpadOfHighestBatteryLevel(out uint npadId, ReadOnlySpan<uint> arg1, AppletResourceUserId appletResourceUserId, ulong pid);
Result GetPalmaConnectionHandle(out PalmaConnectionHandle palmaConnectionHandle, uint arg1, AppletResourceUserId appletResourceUserId, ulong pid);
Result InitializePalma(PalmaConnectionHandle palmaConnectionHandle);
Result AcquirePalmaOperationCompleteEvent(out int arg0, PalmaConnectionHandle palmaConnectionHandle);
@ -144,7 +144,7 @@ namespace Ryujinx.Horizon.Sdk.Hid
Result SetNpadCommunicationMode(AppletResourceUserId appletResourceUserId, long npadCommunicationMode, ulong pid);
Result GetNpadCommunicationMode(out long npadCommunicationMode);
Result SetTouchScreenConfiguration(AppletResourceUserId appletResourceUserId, TouchScreenConfigurationForNx touchScreenConfigurationForNx, ulong pid);
Result IsFirmwareUpdateNeededForNotification(out bool arg0, int arg1, AppletResourceUserId appletResourceUserId, ulong pid);
Result IsFirmwareUpdateNeededForNotification(out bool isFirmwareUpdateNeededForNotification, int unknown, AppletResourceUserId appletResourceUserId, ulong pid);
Result ActivateDigitizer(AppletResourceUserId appletResourceUserId, ulong pid);
}
}

View file

@ -1,9 +1,11 @@
using Ryujinx.Horizon.Sdk.Hid.Npad;
namespace Ryujinx.Horizon.Sdk.Hid.Vibration
{
public struct VibrationDeviceHandle
{
public byte DeviceType;
public byte PlayerId;
public NpadStyleIndex DeviceType;
public NpadIdType PlayerId;
public byte Position;
public byte Reserved;
}

View file

@ -1,8 +0,0 @@
namespace Ryujinx.Horizon.Sdk.Hid.Vibration
{
struct VibrationDeviceValue
{
public VibrationDeviceType DeviceType;
public VibrationDevicePosition Position;
}
}