diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs b/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs index b9235b033..8fe9d3e62 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs @@ -56,6 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid _activeCount = 0; JoyHold = NpadJoyHoldType.Vertical; + SixAxisActive = false; } internal ref KEvent GetStyleSetUpdateEvent(PlayerIndex player) @@ -580,6 +581,23 @@ namespace Ryujinx.HLE.HOS.Services.Hid return needUpdateRight; } + + public bool isAtRest(int playerNumber) + { + + ref NpadInternalState currentNpad = ref _device.Hid.SharedMemory.Npads[playerNumber].InternalState; + ref SixAxisSensorState storage = ref GetSixAxisSensorLifo(ref currentNpad, false).GetCurrentEntryRef(); + + float acceleration = Math.Abs(storage.Acceleration.X) + + Math.Abs(storage.Acceleration.Y) + + Math.Abs(storage.Acceleration.Z); + + float angularVelocity = Math.Abs(storage.AngularVelocity.X) + + Math.Abs(storage.AngularVelocity.Y) + + Math.Abs(storage.AngularVelocity.Z); + + return ((acceleration <= 1.5F) && (angularVelocity <= 1.1F)); + } private void UpdateDisconnectedInputSixAxis(PlayerIndex index) { diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs index 28db75663..a92e1656f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs @@ -602,19 +602,52 @@ namespace Ryujinx.HLE.HOS.Services.Hid } [CommandCmif(82)] - // IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAsRest + // IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAtRest public ResultCode IsSixAxisSensorAtRest(ServiceCtx context) { int sixAxisSensorHandle = context.RequestData.ReadInt32(); + + // 4 byte struct w/ 4-byte alignment + // 0x0 0x4 TypeValue + // 0x0 0x1 NpadStyleIndex + // 0x1 0x1 PlayerNumber + // 0x2 0x1 DeviceIdx + + // uint typeValue = (uint) sixAxisSensorHandle; + // uint npadStyleIndex = (uint) sixAxisSensorHandle & 0xff; + int playerNumber = (sixAxisSensorHandle << 8) & 0xff; + // uint deviceIdx= ((uint) sixAxisSensorHandle << 16) & 0xff; + // uint unknown = ((uint) sixAxisSensorHandle << 24) & 0xff; + + // 32bit sign extension padding + // if = 0, + offset, else - offset + // npadStyleIndex = ((npadStyleIndex & 0x8000) == 0) ? npadStyleIndex | 0xFFFF0000 : npadStyleIndex & 0xFFFF0000; + // playerNumber = ((playerNumber & 0x8000) == 0) ? playerNumber | 0xFFFF0000 : playerNumber & 0xFFFF0000; + // deviceIdx = ((deviceIdx & 0x8000) == 0) ? deviceIdx | 0xFFFF0000 : deviceIdx & 0xFFFF0000; + // unknown = ((unknown & 0x8000) == 0) ? unknown | 0xFFFF0000 : unknown & 0xFFFF0000; + context.RequestData.BaseStream.Position += 4; // Padding long appletResourceUserId = context.RequestData.ReadInt64(); - bool isAtRest = true; - + bool isAtRest; + + // TODO: link to context.Device.Hid.Npads.SixAxisActive when properly implemented + // We currently do not support stopping or starting SixAxisTracking. + // It is just always tracking, the bool is unused. + // See Ryujinx.HLE.HOS.Services.Hid.NpadDevices + + // common cases: if + // controller is keyboard (keyboards don't have gyroscopes, silly goose!) + // controller has no gyroscope + // SixAxisActive == false + // SixAxisTracking == false + // then isAtRest = true + // else check gyroscopic activity + + // check gyroscopic activity + isAtRest = context.Device.Hid.Npads.isAtRest(playerNumber); + context.ResponseData.Write(isAtRest); - - Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, isAtRest }); - return ResultCode.Success; } @@ -629,7 +662,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid context.ResponseData.Write(_isFirmwareUpdateAvailableForSixAxisSensor); Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _isFirmwareUpdateAvailableForSixAxisSensor }); - + return ResultCode.Success; }