diff options
author | emmauss <emmausssss@gmail.com> | 2020-09-29 21:32:42 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-29 23:32:42 +0200 |
commit | 26319d5ab3a4d2f93fc7acb70760d9f96575ee07 (patch) | |
tree | 797d5d828785813d141949decacd6d55f0d4dc0e /Ryujinx.HLE/HOS/Services | |
parent | a6f8a0b01ed3c36d537825de4c27acdec4e7d638 (diff) |
Add Motion controls (#1363)
* Add motion controls
Apply suggestions from code review
Co-authored-by: Ac_K <Acoustik666@gmail.com>
* cleanup
* add reference orientation and derive relative orientation from it
* cleanup
* remove unused variable and strange file
* Review_2.
* change GetInput to TryGetInput
* Review_3.
Co-authored-by: Ac_K <Acoustik666@gmail.com>
Co-authored-by: LDj3SNuD <dvitiello@gmail.com>
Diffstat (limited to 'Ryujinx.HLE/HOS/Services')
4 files changed, 129 insertions, 4 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs index 334af975..0decbfea 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs @@ -1,9 +1,9 @@ +using System; +using System.Collections.Generic; using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Common.Memory; using Ryujinx.HLE.HOS.Kernel.Threading; -using System; -using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Hid { @@ -317,6 +317,89 @@ namespace Ryujinx.HLE.HOS.Services.Hid mainLayout.Entries[(int)mainLayout.Header.LatestEntry] = currentEntry; } + private static SixAxixLayoutsIndex ControllerTypeToSixAxisLayout(ControllerType controllerType) + => controllerType switch + { + ControllerType.ProController => SixAxixLayoutsIndex.ProController, + ControllerType.Handheld => SixAxixLayoutsIndex.Handheld, + ControllerType.JoyconPair => SixAxixLayoutsIndex.JoyDualLeft, + ControllerType.JoyconLeft => SixAxixLayoutsIndex.JoyLeft, + ControllerType.JoyconRight => SixAxixLayoutsIndex.JoyRight, + ControllerType.Pokeball => SixAxixLayoutsIndex.Pokeball, + _ => SixAxixLayoutsIndex.SystemExternal + }; + + public void UpdateSixAxis(IList<SixAxisInput> states) + { + for (int i = 0; i < states.Count; ++i) + { + if (SetSixAxisState(states[i])) + { + i++; + + SetSixAxisState(states[i], true); + } + } + } + + private bool SetSixAxisState(SixAxisInput state, bool isRightPair = false) + { + if (state.PlayerId == PlayerIndex.Unknown) + { + return false; + } + + ref ShMemNpad currentNpad = ref _device.Hid.SharedMemory.Npads[(int)state.PlayerId]; + + if (currentNpad.Header.Type == ControllerType.None) + { + return false; + } + + HidVector accel = new HidVector() + { + X = state.Accelerometer.X, + Y = state.Accelerometer.Y, + Z = state.Accelerometer.Z + }; + + HidVector gyro = new HidVector() + { + X = state.Gyroscope.X, + Y = state.Gyroscope.Y, + Z = state.Gyroscope.Z + }; + + HidVector rotation = new HidVector() + { + X = state.Rotation.X, + Y = state.Rotation.Y, + Z = state.Rotation.Z + }; + + ref NpadSixAxis currentLayout = ref currentNpad.Sixaxis[(int)ControllerTypeToSixAxisLayout(currentNpad.Header.Type) + (isRightPair ? 1 : 0)]; + ref SixAxisState currentEntry = ref currentLayout.Entries[(int)currentLayout.Header.LatestEntry]; + + int previousEntryIndex = (int)(currentLayout.Header.LatestEntry == 0 ? + currentLayout.Header.MaxEntryIndex : currentLayout.Header.LatestEntry - 1); + + ref SixAxisState previousEntry = ref currentLayout.Entries[previousEntryIndex]; + + currentEntry.Accelerometer = accel; + currentEntry.Gyroscope = gyro; + currentEntry.Rotations = rotation; + + unsafe + { + for (int i = 0; i < 9; i++) + { + currentEntry.Orientation[i] = state.Orientation[i]; + } + } + + return currentNpad.Header.Type == ControllerType.JoyconPair && !isRightPair; + } + private void UpdateAllEntries() { ref Array10<ShMemNpad> controllers = ref _device.Hid.SharedMemory.Npads; @@ -359,6 +442,21 @@ namespace Ryujinx.HLE.HOS.Services.Hid break; } } + + ref Array6<NpadSixAxis> sixaxis = ref controllers[i].Sixaxis; + for (int l = 0; l < sixaxis.Length; ++l) + { + ref NpadSixAxis currentLayout = ref sixaxis[l]; + int currentIndex = UpdateEntriesHeader(ref currentLayout.Header, out int previousIndex); + + ref SixAxisState currentEntry = ref currentLayout.Entries[currentIndex]; + SixAxisState previousEntry = currentLayout.Entries[previousIndex]; + + currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1; + currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1; + + currentEntry._unknown2 = 1; + } } } } diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/SixAxisInput.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/SixAxisInput.cs new file mode 100644 index 00000000..4dda82c7 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/SixAxisInput.cs @@ -0,0 +1,13 @@ +using System.Numerics; + +namespace Ryujinx.HLE.HOS.Services.Hid +{ + public struct SixAxisInput + { + public PlayerIndex PlayerId; + public Vector3 Accelerometer; + public Vector3 Gyroscope; + public Vector3 Rotation; + public float[] Orientation; + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisLayoutsIndex.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisLayoutsIndex.cs new file mode 100644 index 00000000..a8795fc0 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisLayoutsIndex.cs @@ -0,0 +1,14 @@ +namespace Ryujinx.HLE.HOS.Services.Hid +{ + enum SixAxixLayoutsIndex : int + { + ProController = 0, + Handheld = 1, + JoyDualLeft = 2, + JoyDualRight = 3, + JoyLeft = 4, + JoyRight = 5, + Pokeball = 6, + SystemExternal = 7 + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs index 0a799916..12974e7e 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/SixAxisState.cs @@ -7,8 +7,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid public ulong SampleTimestamp2; public HidVector Accelerometer; public HidVector Gyroscope; - HidVector unknownSensor; + public HidVector Rotations; public fixed float Orientation[9]; - ulong _unknown2; + public ulong _unknown2; } }
\ No newline at end of file |