diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs index b4a92d6932..957fb9a16b 100644 --- a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs +++ b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs @@ -15,7 +15,6 @@ using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Am.AppletAE.Storage; using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types; using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService; -using Ryujinx.HLE.HOS.Services.Sm; using Ryujinx.HLE.HOS.SystemState; using System; using System.Numerics; @@ -42,6 +41,8 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati private int _notificationStorageChannelEventHandle; private int _healthWarningDisappearedSystemEventHandle; + private bool _gamePlayRecordingState; + private int _jitLoaded; private HorizonClient _horizon; @@ -349,6 +350,15 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati return ResultCode.Success; } + [CommandHipc(65)] // 3.0.0+ + // IsGamePlayRecordingSupported() -> u8 + public ResultCode IsGamePlayRecordingSupported(ServiceCtx context) + { + context.ResponseData.Write(_gamePlayRecordingState); + + return ResultCode.Success; + } + [CommandHipc(66)] // 3.0.0+ // InitializeGamePlayRecording(u64, handle) public ResultCode InitializeGamePlayRecording(ServiceCtx context) @@ -362,9 +372,9 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // SetGamePlayRecordingState(u32) public ResultCode SetGamePlayRecordingState(ServiceCtx context) { - int state = context.RequestData.ReadInt32(); + _gamePlayRecordingState = context.RequestData.ReadInt32() != 0; - Logger.Stub?.PrintStub(LogClass.ServiceAm, new { state }); + Logger.Stub?.PrintStub(LogClass.ServiceAm, new { _gamePlayRecordingState }); return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs index 5f56c770d3..528b6dcea1 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs @@ -21,7 +21,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid private ControllerType[] _configuredTypes; private KEvent[] _styleSetUpdateEvents; private bool[] _supportedPlayers; - private static HidVibrationValue _neutralVibrationValue = new HidVibrationValue + private static VibrationValue _neutralVibrationValue = new VibrationValue { AmplitudeLow = 0f, FrequencyLow = 160f, @@ -33,8 +33,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid internal bool SixAxisActive = false; // TODO: link to hidserver when implemented internal ControllerType SupportedStyleSets { get; set; } - public Dictionary> RumbleQueues = new Dictionary>(); - public Dictionary LastVibrationValues = new Dictionary(); + public Dictionary> RumbleQueues = new Dictionary>(); + public Dictionary LastVibrationValues = new Dictionary(); public NpadDevices(Switch device, bool active = true) : base(device, active) { @@ -588,21 +588,21 @@ namespace Ryujinx.HLE.HOS.Services.Hid WriteNewSixInputEntry(ref currentNpad.JoyRightSixAxisSensor, ref newState); } - public void UpdateRumbleQueue(PlayerIndex index, Dictionary dualVibrationValues) + public void UpdateRumbleQueue(PlayerIndex index, Dictionary dualVibrationValues) { - if (RumbleQueues.TryGetValue(index, out ConcurrentQueue<(HidVibrationValue, HidVibrationValue)> currentQueue)) + if (RumbleQueues.TryGetValue(index, out ConcurrentQueue<(VibrationValue, VibrationValue)> currentQueue)) { - if (!dualVibrationValues.TryGetValue(0, out HidVibrationValue leftVibrationValue)) + if (!dualVibrationValues.TryGetValue(0, out VibrationValue leftVibrationValue)) { leftVibrationValue = _neutralVibrationValue; } - if (!dualVibrationValues.TryGetValue(1, out HidVibrationValue rightVibrationValue)) + if (!dualVibrationValues.TryGetValue(1, out VibrationValue rightVibrationValue)) { rightVibrationValue = _neutralVibrationValue; } - if (!LastVibrationValues.TryGetValue(index, out (HidVibrationValue, HidVibrationValue) dualVibrationValue) || !leftVibrationValue.Equals(dualVibrationValue.Item1) || !rightVibrationValue.Equals(dualVibrationValue.Item2)) + if (!LastVibrationValues.TryGetValue(index, out (VibrationValue, VibrationValue) dualVibrationValue) || !leftVibrationValue.Equals(dualVibrationValue.Item1) || !rightVibrationValue.Equals(dualVibrationValue.Item2)) { currentQueue.Enqueue((leftVibrationValue, rightVibrationValue)); @@ -611,9 +611,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid } } - public HidVibrationValue GetLastVibrationValue(PlayerIndex index, byte position) + public VibrationValue GetLastVibrationValue(PlayerIndex index, byte position) { - if (!LastVibrationValues.TryGetValue(index, out (HidVibrationValue, HidVibrationValue) dualVibrationValue)) + if (!LastVibrationValues.TryGetValue(index, out (VibrationValue, VibrationValue) dualVibrationValue)) { return _neutralVibrationValue; } @@ -621,11 +621,11 @@ namespace Ryujinx.HLE.HOS.Services.Hid return (position == 0) ? dualVibrationValue.Item1 : dualVibrationValue.Item2; } - public ConcurrentQueue<(HidVibrationValue, HidVibrationValue)> GetRumbleQueue(PlayerIndex index) + public ConcurrentQueue<(VibrationValue, VibrationValue)> GetRumbleQueue(PlayerIndex index) { - if (!RumbleQueues.TryGetValue(index, out ConcurrentQueue<(HidVibrationValue, HidVibrationValue)> rumbleQueue)) + if (!RumbleQueues.TryGetValue(index, out ConcurrentQueue<(VibrationValue, VibrationValue)> rumbleQueue)) { - rumbleQueue = new ConcurrentQueue<(HidVibrationValue, HidVibrationValue)>(); + rumbleQueue = new ConcurrentQueue<(VibrationValue, VibrationValue)>(); _device.Hid.Npads.RumbleQueues[index] = rumbleQueue; } diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs index c2cd843291..65a69bb776 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/HidUtils.cs @@ -35,5 +35,10 @@ namespace Ryujinx.HLE.HOS.Services.Hid.HidServer PlayerIndex.Unknown => NpadIdType.Unknown, _ => throw new ArgumentOutOfRangeException(nameof(index)) }; + + public static bool IsValidNpadIdType(NpadIdType npadIdType) + { + return npadIdType <= NpadIdType.Player8 || npadIdType == NpadIdType.Handheld || npadIdType == NpadIdType.Unknown; + } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyAssignmentMode.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyAssignmentMode.cs deleted file mode 100644 index a2e22661de..0000000000 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyAssignmentMode.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - public enum HidNpadJoyAssignmentMode - { - Dual, - Single - } -} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadHandheldActivationMode.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadHandheldActivationMode.cs similarity index 68% rename from Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadHandheldActivationMode.cs rename to Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadHandheldActivationMode.cs index 0aa8334d82..0cf4a0472b 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadHandheldActivationMode.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadHandheldActivationMode.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public enum HidNpadHandheldActivationMode + public enum NpadHandheldActivationMode { Dual, Single, diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyDeviceType.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadJoyDeviceType.cs similarity index 69% rename from Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyDeviceType.cs rename to Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadJoyDeviceType.cs index d0b34def2e..05587bfd21 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/HidNpadJoyDeviceType.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Npad/NpadJoyDeviceType.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public enum HidNpadJoyDeviceType + public enum NpadJoyDeviceType { Left, Right diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidAccelerometerParameters.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/AccelerometerParameters.cs similarity index 70% rename from Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidAccelerometerParameters.cs rename to Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/AccelerometerParameters.cs index fe7e4cc938..4fd0a1b5b5 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidAccelerometerParameters.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/AccelerometerParameters.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public struct HidAccelerometerParameters + public struct AccelerometerParameters { public float X; public float Y; diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidGyroscopeZeroDriftMode.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/GyroscopeZeroDriftMode.cs similarity index 71% rename from Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidGyroscopeZeroDriftMode.cs rename to Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/GyroscopeZeroDriftMode.cs index cd3aa3180c..db7467fa76 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidGyroscopeZeroDriftMode.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/GyroscopeZeroDriftMode.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public enum HidGyroscopeZeroDriftMode + public enum GyroscopeZeroDriftMode { Loose, Standard, diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidSensorFusionParameters.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/SensorFusionParameters.cs similarity index 73% rename from Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidSensorFusionParameters.cs rename to Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/SensorFusionParameters.cs index cadf5ec021..2683ffee41 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/HidSensorFusionParameters.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/SixAxis/SensorFusionParameters.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public struct HidSensorFusionParameters + public struct SensorFusionParameters { public float RevisePower; public float ReviseRange; diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceValue.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceValue.cs deleted file mode 100644 index 7905ecfdc0..0000000000 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceValue.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Hid -{ - public struct HidVibrationDeviceValue - { - public HidVibrationDeviceType DeviceType; - public HidVibrationDevicePosition Position; - } -} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceHandle.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceHandle.cs similarity index 80% rename from Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceHandle.cs rename to Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceHandle.cs index 4501c721a4..fe50e67189 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceHandle.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceHandle.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public struct HidVibrationDeviceHandle + public struct VibrationDeviceHandle { public byte DeviceType; public byte PlayerId; diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDevicePosition.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDevicePosition.cs similarity index 69% rename from Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDevicePosition.cs rename to Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDevicePosition.cs index 0ab84af3d6..117451f163 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDevicePosition.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDevicePosition.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public enum HidVibrationDevicePosition + public enum VibrationDevicePosition { None, Left, diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceType.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceType.cs similarity index 75% rename from Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceType.cs rename to Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceType.cs index 898384be73..4e5557c943 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationDeviceType.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceType.cs @@ -1,6 +1,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid { - public enum HidVibrationDeviceType + public enum VibrationDeviceType { None, LinearResonantActuator, diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceValue.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceValue.cs new file mode 100644 index 0000000000..91a23eb7ef --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationDeviceValue.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Hid +{ + public struct VibrationDeviceValue + { + public VibrationDeviceType DeviceType; + public VibrationDevicePosition Position; + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationValue.cs b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationValue.cs similarity index 78% rename from Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationValue.cs rename to Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationValue.cs index 3f45d26991..38ac9ccacb 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/HidVibrationValue.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidServer/Types/Vibration/VibrationValue.cs @@ -1,9 +1,8 @@ -using Ryujinx.HLE.HOS.Tamper; -using System; +using System; namespace Ryujinx.HLE.HOS.Services.Hid { - public struct HidVibrationValue + public struct VibrationValue { public float AmplitudeLow; public float FrequencyLow; @@ -12,7 +11,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid public override bool Equals(object obj) { - return obj is HidVibrationValue value && + return obj is VibrationValue value && AmplitudeLow == value.AmplitudeLow && AmplitudeHigh == value.AmplitudeHigh; } diff --git a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs index abc76c62f7..957cd55309 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs @@ -5,6 +5,7 @@ using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Hid.HidServer; using Ryujinx.HLE.HOS.Services.Hid.Types; +using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad; using System; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -26,9 +27,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid private bool _isFirmwareUpdateAvailableForSixAxisSensor; private bool _isSixAxisSensorUnalteredPassthroughEnabled; - private HidNpadJoyAssignmentMode _npadJoyAssignmentMode; - private HidNpadHandheldActivationMode _npadHandheldActivationMode; - private HidGyroscopeZeroDriftMode _gyroscopeZeroDriftMode; + private NpadHandheldActivationMode _npadHandheldActivationMode; + private GyroscopeZeroDriftMode _gyroscopeZeroDriftMode; private long _npadCommunicationMode; private uint _accelerometerPlayMode; @@ -37,22 +37,21 @@ namespace Ryujinx.HLE.HOS.Services.Hid #pragma warning restore CS0649 private float _sevenSixAxisSensorFusionStrength; - private HidSensorFusionParameters _sensorFusionParams; - private HidAccelerometerParameters _accelerometerParams; + private SensorFusionParameters _sensorFusionParams; + private AccelerometerParameters _accelerometerParams; public IHidServer(ServiceCtx context) : base(context.Device.System.HidServer) { _xpadIdEvent = new KEvent(context.Device.System.KernelContext); _palmaOperationCompleteEvent = new KEvent(context.Device.System.KernelContext); - _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Dual; - _npadHandheldActivationMode = HidNpadHandheldActivationMode.Dual; - _gyroscopeZeroDriftMode = HidGyroscopeZeroDriftMode.Standard; + _npadHandheldActivationMode = NpadHandheldActivationMode.Dual; + _gyroscopeZeroDriftMode = GyroscopeZeroDriftMode.Standard; _isFirmwareUpdateAvailableForSixAxisSensor = false; - _sensorFusionParams = new HidSensorFusionParameters(); - _accelerometerParams = new HidAccelerometerParameters(); + _sensorFusionParams = new SensorFusionParameters(); + _accelerometerParams = new AccelerometerParameters(); // TODO: signal event at right place _xpadIdEvent.ReadableEvent.Signal(); @@ -393,7 +392,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid int sixAxisSensorHandle = context.RequestData.ReadInt32(); context.RequestData.BaseStream.Position += 4; // Padding - _sensorFusionParams = new HidSensorFusionParameters + _sensorFusionParams = new SensorFusionParameters { RevisePower = context.RequestData.ReadInt32(), ReviseRange = context.RequestData.ReadInt32() @@ -445,7 +444,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid int sixAxisSensorHandle = context.RequestData.ReadInt32(); context.RequestData.BaseStream.Position += 4; // Padding - _accelerometerParams = new HidAccelerometerParameters + _accelerometerParams = new AccelerometerParameters { X = context.RequestData.ReadInt32(), Y = context.RequestData.ReadInt32() @@ -539,7 +538,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid public ResultCode SetGyroscopeZeroDriftMode(ServiceCtx context) { int sixAxisSensorHandle = context.RequestData.ReadInt32(); - _gyroscopeZeroDriftMode = (HidGyroscopeZeroDriftMode)context.RequestData.ReadInt32(); + _gyroscopeZeroDriftMode = (GyroscopeZeroDriftMode)context.RequestData.ReadInt32(); long appletResourceUserId = context.RequestData.ReadInt64(); Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _gyroscopeZeroDriftMode }); @@ -570,7 +569,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid context.RequestData.BaseStream.Position += 4; // Padding long appletResourceUserId = context.RequestData.ReadInt64(); - _gyroscopeZeroDriftMode = HidGyroscopeZeroDriftMode.Standard; + _gyroscopeZeroDriftMode = GyroscopeZeroDriftMode.Standard; Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _gyroscopeZeroDriftMode }); @@ -909,54 +908,63 @@ namespace Ryujinx.HLE.HOS.Services.Hid // SetNpadJoyAssignmentModeSingleByDefault(uint HidControllerId, nn::applet::AppletResourceUserId) public ResultCode SetNpadJoyAssignmentModeSingleByDefault(ServiceCtx context) { - PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32(); - long appletResourceUserId = context.RequestData.ReadInt64(); + NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadUInt32(); + context.RequestData.BaseStream.Position += 4; // Padding + long appletResourceUserId = context.RequestData.ReadInt64(); - _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single; - - Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, _npadJoyAssignmentMode }); + if (HidUtils.IsValidNpadIdType(npadIdType)) + { + context.Device.Hid.SharedMemory.Npads[(int)HidUtils.GetIndexFromNpadIdType(npadIdType)].InternalState.JoyAssignmentMode = NpadJoyAssignmentMode.Single; + } return ResultCode.Success; } [CommandHipc(123)] - // SetNpadJoyAssignmentModeSingle(uint HidControllerId, nn::applet::AppletResourceUserId, long HidNpadJoyDeviceType) + // SetNpadJoyAssignmentModeSingle(uint npadIdType, nn::applet::AppletResourceUserId, uint npadJoyDeviceType) public ResultCode SetNpadJoyAssignmentModeSingle(ServiceCtx context) { - PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32(); - long appletResourceUserId = context.RequestData.ReadInt64(); - HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64(); + NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadUInt32(); + context.RequestData.BaseStream.Position += 4; // Padding + long appletResourceUserId = context.RequestData.ReadInt64(); + NpadJoyDeviceType npadJoyDeviceType = (NpadJoyDeviceType)context.RequestData.ReadUInt32(); - _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single; - - Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, hidNpadJoyDeviceType, _npadJoyAssignmentMode }); + if (HidUtils.IsValidNpadIdType(npadIdType)) + { + SetNpadJoyAssignmentModeSingleWithDestinationImpl(context, npadIdType, appletResourceUserId, npadJoyDeviceType, out _, out _); + } return ResultCode.Success; } [CommandHipc(124)] - // SetNpadJoyAssignmentModeDual(uint HidControllerId, nn::applet::AppletResourceUserId) + // SetNpadJoyAssignmentModeDual(uint npadIdType, nn::applet::AppletResourceUserId) public ResultCode SetNpadJoyAssignmentModeDual(ServiceCtx context) { - PlayerIndex hidControllerId = HidUtils.GetIndexFromNpadIdType((NpadIdType)context.RequestData.ReadInt32()); - long appletResourceUserId = context.RequestData.ReadInt64(); + NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadUInt32(); + context.RequestData.BaseStream.Position += 4; // Padding + long appletResourceUserId = context.RequestData.ReadInt64(); - _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Dual; - - Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, _npadJoyAssignmentMode }); + if (HidUtils.IsValidNpadIdType(npadIdType)) + { + context.Device.Hid.SharedMemory.Npads[(int)HidUtils.GetIndexFromNpadIdType(npadIdType)].InternalState.JoyAssignmentMode = NpadJoyAssignmentMode.Dual; + } return ResultCode.Success; } [CommandHipc(125)] - // MergeSingleJoyAsDualJoy(uint SingleJoyId0, uint SingleJoyId1, nn::applet::AppletResourceUserId) + // MergeSingleJoyAsDualJoy(uint npadIdType0, uint npadIdType1, nn::applet::AppletResourceUserId) public ResultCode MergeSingleJoyAsDualJoy(ServiceCtx context) { - long singleJoyId0 = context.RequestData.ReadInt32(); - long singleJoyId1 = context.RequestData.ReadInt32(); - long appletResourceUserId = context.RequestData.ReadInt64(); + NpadIdType npadIdType0 = (NpadIdType)context.RequestData.ReadUInt32(); + NpadIdType npadIdType1 = (NpadIdType)context.RequestData.ReadUInt32(); + long appletResourceUserId = context.RequestData.ReadInt64(); - Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, singleJoyId0, singleJoyId1 }); + if (HidUtils.IsValidNpadIdType(npadIdType0) && HidUtils.IsValidNpadIdType(npadIdType1)) + { + Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, npadIdType0, npadIdType1 }); + } return ResultCode.Success; } @@ -988,7 +996,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid public ResultCode SetNpadHandheldActivationMode(ServiceCtx context) { long appletResourceUserId = context.RequestData.ReadInt64(); - _npadHandheldActivationMode = (HidNpadHandheldActivationMode)context.RequestData.ReadInt64(); + _npadHandheldActivationMode = (NpadHandheldActivationMode)context.RequestData.ReadInt64(); Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadHandheldActivationMode }); @@ -1049,37 +1057,47 @@ namespace Ryujinx.HLE.HOS.Services.Hid } [CommandHipc(133)] // 5.0.0+ - // SetNpadJoyAssignmentModeSingleWithDestination(uint HidControllerId, long HidNpadJoyDeviceType, nn::applet::AppletResourceUserId) -> bool Unknown0, uint Unknown1 + // SetNpadJoyAssignmentModeSingleWithDestination(uint npadIdType, uint npadJoyDeviceType, nn::applet::AppletResourceUserId) -> bool npadIdTypeIsSet, uint npadIdTypeSet public ResultCode SetNpadJoyAssignmentModeSingleWithDestination(ServiceCtx context) { - PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32(); - HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64(); - long appletResourceUserId = context.RequestData.ReadInt64(); + NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadInt32(); + NpadJoyDeviceType npadJoyDeviceType = (NpadJoyDeviceType)context.RequestData.ReadInt32(); + context.RequestData.BaseStream.Position += 4; // Padding + long appletResourceUserId = context.RequestData.ReadInt64(); - _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single; + if (HidUtils.IsValidNpadIdType(npadIdType)) + { + SetNpadJoyAssignmentModeSingleWithDestinationImpl(context, npadIdType, appletResourceUserId, npadJoyDeviceType, out NpadIdType npadIdTypeSet, out bool npadIdTypeIsSet); - context.ResponseData.Write(0); //Unknown0 - context.ResponseData.Write(0); //Unknown1 - - Logger.Stub?.PrintStub(LogClass.ServiceHid, new { - appletResourceUserId, - hidControllerId, - hidNpadJoyDeviceType, - _npadJoyAssignmentMode, - Unknown0 = 0, - Unknown1 = 0 - }); + if (npadIdTypeIsSet) + { + context.ResponseData.Write(npadIdTypeIsSet); + context.ResponseData.Write((uint)npadIdTypeSet); + } + } return ResultCode.Success; } + private void SetNpadJoyAssignmentModeSingleWithDestinationImpl(ServiceCtx context, NpadIdType npadIdType, long appletResourceUserId, NpadJoyDeviceType npadJoyDeviceType, out NpadIdType npadIdTypeSet, out bool npadIdTypeIsSet) + { + npadIdTypeSet = default; + npadIdTypeIsSet = false; + + context.Device.Hid.SharedMemory.Npads[(int)HidUtils.GetIndexFromNpadIdType(npadIdType)].InternalState.JoyAssignmentMode = NpadJoyAssignmentMode.Single; + + // TODO: Service seems to use the npadJoyDeviceType to find the nearest other Npad available and merge them to dual. + // If one is found, it returns the npadIdType of the other Npad and a bool. + // If not, it returns nothing. + } + [CommandHipc(200)] // GetVibrationDeviceInfo(nn::hid::VibrationDeviceHandle) -> nn::hid::VibrationDeviceInfo public ResultCode GetVibrationDeviceInfo(ServiceCtx context) { - HidVibrationDeviceHandle deviceHandle = context.RequestData.ReadStruct(); - NpadStyleIndex deviceType = (NpadStyleIndex)deviceHandle.DeviceType; - NpadIdType npadIdType = (NpadIdType)deviceHandle.PlayerId; + VibrationDeviceHandle deviceHandle = context.RequestData.ReadStruct(); + NpadStyleIndex deviceType = (NpadStyleIndex)deviceHandle.DeviceType; + NpadIdType npadIdType = (NpadIdType)deviceHandle.PlayerId; if (deviceType < NpadStyleIndex.System || deviceType >= NpadStyleIndex.FullKey) { @@ -1093,28 +1111,28 @@ namespace Ryujinx.HLE.HOS.Services.Hid return ResultCode.InvalidDeviceIndex; } - HidVibrationDeviceType vibrationDeviceType = HidVibrationDeviceType.None; + VibrationDeviceType vibrationDeviceType = VibrationDeviceType.None; - if (Enum.IsDefined(deviceType)) + if (Enum.IsDefined(deviceType)) { - vibrationDeviceType = HidVibrationDeviceType.LinearResonantActuator; + vibrationDeviceType = VibrationDeviceType.LinearResonantActuator; } else if ((uint)deviceType == 8) { - vibrationDeviceType = HidVibrationDeviceType.GcErm; + vibrationDeviceType = VibrationDeviceType.GcErm; } - HidVibrationDevicePosition vibrationDevicePosition = HidVibrationDevicePosition.None; + VibrationDevicePosition vibrationDevicePosition = VibrationDevicePosition.None; - if (vibrationDeviceType == HidVibrationDeviceType.LinearResonantActuator) + if (vibrationDeviceType == VibrationDeviceType.LinearResonantActuator) { if (deviceHandle.Position == 0) { - vibrationDevicePosition = HidVibrationDevicePosition.Left; + vibrationDevicePosition = VibrationDevicePosition.Left; } else if (deviceHandle.Position == 1) { - vibrationDevicePosition = HidVibrationDevicePosition.Right; + vibrationDevicePosition = VibrationDevicePosition.Right; } else { @@ -1122,7 +1140,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid } } - HidVibrationDeviceValue deviceInfo = new HidVibrationDeviceValue + VibrationDeviceValue deviceInfo = new VibrationDeviceValue { DeviceType = vibrationDeviceType, Position = vibrationDevicePosition @@ -1140,7 +1158,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid // SendVibrationValue(nn::hid::VibrationDeviceHandle, nn::hid::VibrationValue, nn::applet::AppletResourceUserId) public ResultCode SendVibrationValue(ServiceCtx context) { - HidVibrationDeviceHandle deviceHandle = new HidVibrationDeviceHandle + VibrationDeviceHandle deviceHandle = new VibrationDeviceHandle { DeviceType = context.RequestData.ReadByte(), PlayerId = context.RequestData.ReadByte(), @@ -1148,7 +1166,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid Reserved = context.RequestData.ReadByte() }; - HidVibrationValue vibrationValue = new HidVibrationValue + VibrationValue vibrationValue = new VibrationValue { AmplitudeLow = context.RequestData.ReadSingle(), FrequencyLow = context.RequestData.ReadSingle(), @@ -1158,7 +1176,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid long appletResourceUserId = context.RequestData.ReadInt64(); - Dictionary dualVibrationValues = new Dictionary(); + Dictionary dualVibrationValues = new Dictionary(); dualVibrationValues[deviceHandle.Position] = vibrationValue; @@ -1171,7 +1189,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid // GetActualVibrationValue(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationValue public ResultCode GetActualVibrationValue(ServiceCtx context) { - HidVibrationDeviceHandle deviceHandle = new HidVibrationDeviceHandle + VibrationDeviceHandle deviceHandle = new VibrationDeviceHandle { DeviceType = context.RequestData.ReadByte(), PlayerId = context.RequestData.ReadByte(), @@ -1181,7 +1199,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid long appletResourceUserId = context.RequestData.ReadInt64(); - HidVibrationValue vibrationValue = context.Device.Hid.Npads.GetLastVibrationValue((PlayerIndex)deviceHandle.PlayerId, deviceHandle.Position); + VibrationValue vibrationValue = context.Device.Hid.Npads.GetLastVibrationValue((PlayerIndex)deviceHandle.PlayerId, deviceHandle.Position); context.ResponseData.Write(vibrationValue.AmplitudeLow); context.ResponseData.Write(vibrationValue.FrequencyLow); @@ -1234,12 +1252,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid context.Memory.Read(context.Request.PtrBuff[1].Position, vibrationValueBuffer); - Span deviceHandles = MemoryMarshal.Cast(vibrationDeviceHandleBuffer); - Span vibrationValues = MemoryMarshal.Cast(vibrationValueBuffer); + Span deviceHandles = MemoryMarshal.Cast(vibrationDeviceHandleBuffer); + Span vibrationValues = MemoryMarshal.Cast(vibrationValueBuffer); if (!deviceHandles.IsEmpty && vibrationValues.Length == deviceHandles.Length) { - Dictionary dualVibrationValues = new Dictionary(); + Dictionary dualVibrationValues = new Dictionary(); PlayerIndex currentIndex = (PlayerIndex)deviceHandles[0].PlayerId; for (int deviceCounter = 0; deviceCounter < deviceHandles.Length; deviceCounter++) @@ -1250,7 +1268,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid if (index != currentIndex || dualVibrationValues.Count == 2) { context.Device.Hid.Npads.UpdateRumbleQueue(currentIndex, dualVibrationValues); - dualVibrationValues = new Dictionary(); + dualVibrationValues = new Dictionary(); } dualVibrationValues[position] = vibrationValues[deviceCounter]; diff --git a/Ryujinx.Input/HLE/NpadController.cs b/Ryujinx.Input/HLE/NpadController.cs index 1e0789b776..6706ad0b6a 100644 --- a/Ryujinx.Input/HLE/NpadController.cs +++ b/Ryujinx.Input/HLE/NpadController.cs @@ -543,14 +543,14 @@ namespace Ryujinx.Input.HLE Dispose(true); } - public void UpdateRumble(ConcurrentQueue<(HidVibrationValue, HidVibrationValue)> queue) + public void UpdateRumble(ConcurrentQueue<(VibrationValue, VibrationValue)> queue) { - if (queue.TryDequeue(out (HidVibrationValue, HidVibrationValue) dualVibrationValue)) + if (queue.TryDequeue(out (VibrationValue, VibrationValue) dualVibrationValue)) { if (_config is StandardControllerInputConfig controllerConfig && controllerConfig.Rumble.EnableRumble) { - HidVibrationValue leftVibrationValue = dualVibrationValue.Item1; - HidVibrationValue rightVibrationValue = dualVibrationValue.Item2; + VibrationValue leftVibrationValue = dualVibrationValue.Item1; + VibrationValue rightVibrationValue = dualVibrationValue.Item2; float low = Math.Min(1f, (float)((rightVibrationValue.AmplitudeLow * 0.85 + rightVibrationValue.AmplitudeHigh * 0.15) * controllerConfig.Rumble.StrongRumble)); float high = Math.Min(1f, (float)((leftVibrationValue.AmplitudeLow * 0.15 + leftVibrationValue.AmplitudeHigh * 0.85) * controllerConfig.Rumble.WeakRumble));