hid: Cleanup and implement some calls (#2380)

This commit is contained in:
Ac_K 2021-06-23 22:52:55 +02:00 committed by GitHub
parent 9efe124fc5
commit eb23933331
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 205 additions and 63 deletions

View file

@ -239,45 +239,51 @@ namespace Ryujinx.HLE.HOS.Services.Hid
switch (type) switch (type)
{ {
case ControllerType.ProController: case ControllerType.ProController:
controller.StyleSet = NpadStyleTag.FullKey; controller.StyleSet = NpadStyleTag.FullKey;
controller.DeviceType = DeviceType.FullKey; controller.DeviceType = DeviceType.FullKey;
controller.SystemProperties |= NpadSystemProperties.IsAbxyButtonOriented | controller.SystemProperties |= NpadSystemProperties.IsAbxyButtonOriented |
NpadSystemProperties.IsPlusAvailable | NpadSystemProperties.IsPlusAvailable |
NpadSystemProperties.IsMinusAvailable; NpadSystemProperties.IsMinusAvailable;
controller.AppletFooterUiType = AppletFooterUiType.SwitchProController;
break; break;
case ControllerType.Handheld: case ControllerType.Handheld:
controller.StyleSet = NpadStyleTag.Handheld; controller.StyleSet = NpadStyleTag.Handheld;
controller.DeviceType = DeviceType.HandheldLeft | controller.DeviceType = DeviceType.HandheldLeft |
DeviceType.HandheldRight; DeviceType.HandheldRight;
controller.SystemProperties |= NpadSystemProperties.IsAbxyButtonOriented | controller.SystemProperties |= NpadSystemProperties.IsAbxyButtonOriented |
NpadSystemProperties.IsPlusAvailable | NpadSystemProperties.IsPlusAvailable |
NpadSystemProperties.IsMinusAvailable; NpadSystemProperties.IsMinusAvailable;
controller.AppletFooterUiType = AppletFooterUiType.HandheldJoyConLeftJoyConRight;
break; break;
case ControllerType.JoyconPair: case ControllerType.JoyconPair:
controller.StyleSet = NpadStyleTag.JoyDual; controller.StyleSet = NpadStyleTag.JoyDual;
controller.DeviceType = DeviceType.JoyLeft | controller.DeviceType = DeviceType.JoyLeft |
DeviceType.JoyRight; DeviceType.JoyRight;
controller.SystemProperties |= NpadSystemProperties.IsAbxyButtonOriented | controller.SystemProperties |= NpadSystemProperties.IsAbxyButtonOriented |
NpadSystemProperties.IsPlusAvailable | NpadSystemProperties.IsPlusAvailable |
NpadSystemProperties.IsMinusAvailable; NpadSystemProperties.IsMinusAvailable;
controller.AppletFooterUiType = _device.System.State.DockedMode ? AppletFooterUiType.JoyDual : AppletFooterUiType.HandheldJoyConLeftJoyConRight;
break; break;
case ControllerType.JoyconLeft: case ControllerType.JoyconLeft:
controller.StyleSet = NpadStyleTag.JoyLeft; controller.StyleSet = NpadStyleTag.JoyLeft;
controller.JoyAssignmentMode = NpadJoyAssignmentMode.Single; controller.JoyAssignmentMode = NpadJoyAssignmentMode.Single;
controller.DeviceType = DeviceType.JoyLeft; controller.DeviceType = DeviceType.JoyLeft;
controller.SystemProperties |= NpadSystemProperties.IsSlSrButtonOriented | controller.SystemProperties |= NpadSystemProperties.IsSlSrButtonOriented |
NpadSystemProperties.IsMinusAvailable; NpadSystemProperties.IsMinusAvailable;
controller.AppletFooterUiType = _device.System.State.DockedMode ? AppletFooterUiType.JoyDualLeftOnly : AppletFooterUiType.HandheldJoyConLeftOnly;
break; break;
case ControllerType.JoyconRight: case ControllerType.JoyconRight:
controller.StyleSet = NpadStyleTag.JoyRight; controller.StyleSet = NpadStyleTag.JoyRight;
controller.JoyAssignmentMode = NpadJoyAssignmentMode.Single; controller.JoyAssignmentMode = NpadJoyAssignmentMode.Single;
controller.DeviceType = DeviceType.JoyRight; controller.DeviceType = DeviceType.JoyRight;
controller.SystemProperties |= NpadSystemProperties.IsSlSrButtonOriented | controller.SystemProperties |= NpadSystemProperties.IsSlSrButtonOriented |
NpadSystemProperties.IsPlusAvailable; NpadSystemProperties.IsPlusAvailable;
controller.AppletFooterUiType = _device.System.State.DockedMode ? AppletFooterUiType.JoyDualRightOnly : AppletFooterUiType.HandheldJoyConRightOnly;
break; break;
case ControllerType.Pokeball: case ControllerType.Pokeball:
controller.StyleSet = NpadStyleTag.Palma; controller.StyleSet = NpadStyleTag.Palma;
controller.DeviceType = DeviceType.Palma; controller.DeviceType = DeviceType.Palma;
controller.AppletFooterUiType = AppletFooterUiType.None;
break; break;
} }

View file

@ -35,19 +35,5 @@ namespace Ryujinx.HLE.HOS.Services.Hid.HidServer
PlayerIndex.Unknown => NpadIdType.Unknown, PlayerIndex.Unknown => NpadIdType.Unknown,
_ => throw new ArgumentOutOfRangeException(nameof(index)) _ => throw new ArgumentOutOfRangeException(nameof(index))
}; };
public static long GetLedPatternFromNpadId(NpadIdType npadIdType)
=> npadIdType switch
{
NpadIdType.Player1 => 0b0001,
NpadIdType.Player2 => 0b0011,
NpadIdType.Player3 => 0b0111,
NpadIdType.Player4 => 0b1111,
NpadIdType.Player5 => 0b1001,
NpadIdType.Player6 => 0b0101,
NpadIdType.Player7 => 0b1101,
NpadIdType.Player8 => 0b0110,
_ => 0b0000
};
} }
} }

View file

@ -746,22 +746,33 @@ namespace Ryujinx.HLE.HOS.Services.Hid
} }
[CommandHipc(108)] [CommandHipc(108)]
// GetPlayerLedPattern(uint NpadId) -> ulong LedPattern // GetPlayerLedPattern(u32 npad_id) -> u64 led_pattern
public ResultCode GetPlayerLedPattern(ServiceCtx context) public ResultCode GetPlayerLedPattern(ServiceCtx context)
{ {
NpadIdType npadId = (NpadIdType)context.RequestData.ReadInt32(); NpadIdType npadId = (NpadIdType)context.RequestData.ReadUInt32();
long ledPattern = HidUtils.GetLedPatternFromNpadId(npadId); ulong ledPattern = npadId switch
{
NpadIdType.Player1 => 0b0001,
NpadIdType.Player2 => 0b0011,
NpadIdType.Player3 => 0b0111,
NpadIdType.Player4 => 0b1111,
NpadIdType.Player5 => 0b1001,
NpadIdType.Player6 => 0b0101,
NpadIdType.Player7 => 0b1101,
NpadIdType.Player8 => 0b0110,
NpadIdType.Unknown => 0b0000,
NpadIdType.Handheld => 0b0000,
_ => throw new ArgumentOutOfRangeException(nameof(npadId))
};
context.ResponseData.Write(ledPattern); context.ResponseData.Write(ledPattern);
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, ledPattern });
return ResultCode.Success; return ResultCode.Success;
} }
[CommandHipc(109)] // 5.0.0+ [CommandHipc(109)] // 5.0.0+
// ActivateNpadWithRevision(nn::applet::AppletResourceUserId, int Unknown) // ActivateNpadWithRevision(nn::applet::AppletResourceUserId, int revision)
public ResultCode ActivateNpadWithRevision(ServiceCtx context) public ResultCode ActivateNpadWithRevision(ServiceCtx context)
{ {
int revision = context.RequestData.ReadInt32(); int revision = context.RequestData.ReadInt32();
@ -798,32 +809,46 @@ namespace Ryujinx.HLE.HOS.Services.Hid
} }
[CommandHipc(120)] [CommandHipc(120)]
// SetNpadJoyHoldType(nn::applet::AppletResourceUserId, long NpadJoyHoldType) // SetNpadJoyHoldType(nn::applet::AppletResourceUserId, ulong NpadJoyHoldType)
public ResultCode SetNpadJoyHoldType(ServiceCtx context) public ResultCode SetNpadJoyHoldType(ServiceCtx context)
{ {
long appletResourceUserId = context.RequestData.ReadInt64(); long appletResourceUserId = context.RequestData.ReadInt64();
context.Device.Hid.Npads.JoyHold = (NpadJoyHoldType)context.RequestData.ReadInt64();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { NpadJoyHoldType npadJoyHoldType = (NpadJoyHoldType)context.RequestData.ReadUInt64();
appletResourceUserId,
context.Device.Hid.Npads.JoyHold if (npadJoyHoldType > NpadJoyHoldType.Horizontal)
}); {
throw new ArgumentOutOfRangeException(nameof(npadJoyHoldType));
}
foreach (PlayerIndex playerIndex in context.Device.Hid.Npads.GetSupportedPlayers())
{
if (HidUtils.GetNpadIdTypeFromIndex(playerIndex) > NpadIdType.Handheld)
{
return ResultCode.InvalidNpadIdType;
}
}
context.Device.Hid.Npads.JoyHold = npadJoyHoldType;
return ResultCode.Success; return ResultCode.Success;
} }
[CommandHipc(121)] [CommandHipc(121)]
// GetNpadJoyHoldType(nn::applet::AppletResourceUserId) -> long NpadJoyHoldType // GetNpadJoyHoldType(nn::applet::AppletResourceUserId) -> ulong NpadJoyHoldType
public ResultCode GetNpadJoyHoldType(ServiceCtx context) public ResultCode GetNpadJoyHoldType(ServiceCtx context)
{ {
long appletResourceUserId = context.RequestData.ReadInt64(); long appletResourceUserId = context.RequestData.ReadInt64();
context.ResponseData.Write((long)context.Device.Hid.Npads.JoyHold); foreach (PlayerIndex playerIndex in context.Device.Hid.Npads.GetSupportedPlayers())
{
if (HidUtils.GetNpadIdTypeFromIndex(playerIndex) > NpadIdType.Handheld)
{
return ResultCode.InvalidNpadIdType;
}
}
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { context.ResponseData.Write((ulong)context.Device.Hid.Npads.JoyHold);
appletResourceUserId,
context.Device.Hid.Npads.JoyHold
});
return ResultCode.Success; return ResultCode.Success;
} }
@ -1171,6 +1196,21 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success; return ResultCode.Success;
} }
[CommandHipc(211)] // 7.0.0+
// IsVibrationDeviceMounted(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId)
public ResultCode IsVibrationDeviceMounted(ServiceCtx context)
{
int vibrationDeviceHandle = context.RequestData.ReadInt32();
long appletResourceUserId = context.RequestData.ReadInt64();
// NOTE: Service use vibrationDeviceHandle to get the PlayerIndex.
// And return false if (npadIdType >= (NpadIdType)8 && npadIdType != NpadIdType.Handheld && npadIdType != NpadIdType.Unknown)
context.ResponseData.Write(true);
return ResultCode.Success;
}
[CommandHipc(300)] [CommandHipc(300)]
// ActivateConsoleSixAxisSensor(nn::applet::AppletResourceUserId) // ActivateConsoleSixAxisSensor(nn::applet::AppletResourceUserId)
public ResultCode ActivateConsoleSixAxisSensor(ServiceCtx context) public ResultCode ActivateConsoleSixAxisSensor(ServiceCtx context)

View file

@ -1,8 +1,76 @@
namespace Ryujinx.HLE.HOS.Services.Hid using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Services.Hid.HidServer;
using Ryujinx.HLE.HOS.Services.Hid.Types;
namespace Ryujinx.HLE.HOS.Services.Hid
{ {
[Service("hid:sys")] [Service("hid:sys")]
class IHidSystemServer : IpcService class IHidSystemServer : IpcService
{ {
public IHidSystemServer(ServiceCtx context) { } public IHidSystemServer(ServiceCtx context) { }
[CommandHipc(303)]
// ApplyNpadSystemCommonPolicy(u64)
public ResultCode ApplyNpadSystemCommonPolicy(ServiceCtx context)
{
ulong commonPolicy = context.RequestData.ReadUInt64();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { commonPolicy });
return ResultCode.Success;
}
[CommandHipc(306)]
// GetLastActiveNpad(u32) -> u8, u8
public ResultCode GetLastActiveNpad(ServiceCtx context)
{
// TODO: RequestData seems to have garbage data, reading an extra uint seems to fix the issue.
context.RequestData.ReadUInt32();
ResultCode resultCode = GetAppletFooterUiTypeImpl(context, out AppletFooterUiType appletFooterUiType);
context.ResponseData.Write((byte)appletFooterUiType);
context.ResponseData.Write((byte)0);
return resultCode;
}
[CommandHipc(307)]
// GetNpadSystemExtStyle() -> u64
public ResultCode GetNpadSystemExtStyle(ServiceCtx context)
{
foreach (PlayerIndex playerIndex in context.Device.Hid.Npads.GetSupportedPlayers())
{
if (HidUtils.GetNpadIdTypeFromIndex(playerIndex) > NpadIdType.Handheld)
{
return ResultCode.InvalidNpadIdType;
}
}
context.ResponseData.Write((ulong)context.Device.Hid.Npads.SupportedStyleSets);
return ResultCode.Success;
}
[CommandHipc(314)] // 9.0.0+
// GetAppletFooterUiType(u32) -> u8
public ResultCode GetAppletFooterUiType(ServiceCtx context)
{
ResultCode resultCode = GetAppletFooterUiTypeImpl(context, out AppletFooterUiType appletFooterUiType);
context.ResponseData.Write((byte)appletFooterUiType);
return resultCode;
}
private ResultCode GetAppletFooterUiTypeImpl(ServiceCtx context, out AppletFooterUiType appletFooterUiType)
{
NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadUInt32();
PlayerIndex playerIndex = HidUtils.GetIndexFromNpadIdType(npadIdType);
appletFooterUiType = context.Device.Hid.SharedMemory.Npads[(int)playerIndex].InternalState.AppletFooterUiType;
return ResultCode.Success;
}
} }
} }

View file

@ -0,0 +1,12 @@
namespace Ryujinx.HLE.HOS.Services.Hid
{
enum ResultCode
{
ModuleId = 202,
ErrorCodeShift = 9,
Success = 0,
InvalidNpadIdType = (710 << ErrorCodeShift) | ModuleId
}
}

View file

@ -0,0 +1,30 @@
using System;
namespace Ryujinx.HLE.HOS.Services.Hid.Types
{
[Flags]
enum AppletFooterUiType : byte
{
None,
HandheldNone,
HandheldJoyConLeftOnly,
HandheldJoyConRightOnly,
HandheldJoyConLeftJoyConRight,
JoyDual,
JoyDualLeftOnly,
JoyDualRightOnly,
JoyLeftHorizontal,
JoyLeftVertical,
JoyRightHorizontal,
JoyRightVertical,
SwitchProController,
CompatibleProController,
CompatibleJoyCon,
LarkHvc1,
LarkHvc2,
LarkNesLeft,
LarkNesRight,
Lucia,
Verification
}
}

View file

@ -29,7 +29,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
public NpadBatteryLevel BatteryLevelJoyLeft; public NpadBatteryLevel BatteryLevelJoyLeft;
public NpadBatteryLevel BatteryLevelJoyRight; public NpadBatteryLevel BatteryLevelJoyRight;
public uint AppletFooterUiAttributes; public uint AppletFooterUiAttributes;
public byte AppletFooterUiType; public AppletFooterUiType AppletFooterUiType;
private unsafe fixed byte _reserved2[0x7B]; private unsafe fixed byte _reserved2[0x7B];
public RingLifo<NpadGcTriggerState> GcTrigger; public RingLifo<NpadGcTriggerState> GcTrigger;
public NpadLarkType LarkTypeLeftAndMain; public NpadLarkType LarkTypeLeftAndMain;