using Ryujinx.Common; using Ryujinx.HLE.HOS; namespace Ryujinx.HLE.Input { public partial class Hid { private Switch _device; public HidControllerBase PrimaryController { get; private set; } internal long HidPosition; public Hid(Switch device, long hidPosition) { this._device = device; this.HidPosition = hidPosition; device.Memory.FillWithZeros(hidPosition, Horizon.HidSize); } public void InitilizePrimaryController(HidControllerType controllerType) { HidControllerId controllerId = controllerType == HidControllerType.Handheld ? HidControllerId.ControllerHandheld : HidControllerId.ControllerPlayer1; if (controllerType == HidControllerType.ProController) { PrimaryController = new HidProController(_device); } else { PrimaryController = new HidNpadController(controllerType, _device, (NpadColor.BodyNeonRed, NpadColor.BodyNeonRed), (NpadColor.ButtonsNeonBlue, NpadColor.ButtonsNeonBlue)); } PrimaryController.Connect(controllerId); } private HidControllerButtons UpdateStickButtons( HidJoystickPosition leftStick, HidJoystickPosition rightStick) { HidControllerButtons result = 0; if (rightStick.Dx < 0) { result |= HidControllerButtons.RStickLeft; } if (rightStick.Dx > 0) { result |= HidControllerButtons.RStickRight; } if (rightStick.Dy < 0) { result |= HidControllerButtons.RStickDown; } if (rightStick.Dy > 0) { result |= HidControllerButtons.RStickUp; } if (leftStick.Dx < 0) { result |= HidControllerButtons.LStickLeft; } if (leftStick.Dx > 0) { result |= HidControllerButtons.LStickRight; } if (leftStick.Dy < 0) { result |= HidControllerButtons.LStickDown; } if (leftStick.Dy > 0) { result |= HidControllerButtons.LStickUp; } return result; } public void SetTouchPoints(params HidTouchPoint[] points) { long touchScreenOffset = HidPosition + HidTouchScreenOffset; long lastEntry = _device.Memory.ReadInt64(touchScreenOffset + 0x10); long currEntry = (lastEntry + 1) % HidEntryCount; long timestamp = GetTimestamp(); _device.Memory.WriteInt64(touchScreenOffset + 0x00, timestamp); _device.Memory.WriteInt64(touchScreenOffset + 0x08, HidEntryCount); _device.Memory.WriteInt64(touchScreenOffset + 0x10, currEntry); _device.Memory.WriteInt64(touchScreenOffset + 0x18, HidEntryCount - 1); _device.Memory.WriteInt64(touchScreenOffset + 0x20, timestamp); long touchEntryOffset = touchScreenOffset + HidTouchHeaderSize; long lastEntryOffset = touchEntryOffset + lastEntry * HidTouchEntrySize; long sampleCounter = _device.Memory.ReadInt64(lastEntryOffset) + 1; touchEntryOffset += currEntry * HidTouchEntrySize; _device.Memory.WriteInt64(touchEntryOffset + 0x00, sampleCounter); _device.Memory.WriteInt64(touchEntryOffset + 0x08, points.Length); touchEntryOffset += HidTouchEntryHeaderSize; const int padding = 0; int index = 0; foreach (HidTouchPoint point in points) { _device.Memory.WriteInt64(touchEntryOffset + 0x00, sampleCounter); _device.Memory.WriteInt32(touchEntryOffset + 0x08, padding); _device.Memory.WriteInt32(touchEntryOffset + 0x0c, index++); _device.Memory.WriteInt32(touchEntryOffset + 0x10, point.X); _device.Memory.WriteInt32(touchEntryOffset + 0x14, point.Y); _device.Memory.WriteInt32(touchEntryOffset + 0x18, point.DiameterX); _device.Memory.WriteInt32(touchEntryOffset + 0x1c, point.DiameterY); _device.Memory.WriteInt32(touchEntryOffset + 0x20, point.Angle); _device.Memory.WriteInt32(touchEntryOffset + 0x24, padding); touchEntryOffset += HidTouchEntryTouchSize; } } internal static long GetTimestamp() { return PerformanceCounter.ElapsedMilliseconds * 19200; } } }