diff options
Diffstat (limited to 'Ryujinx.HLE/Input/Controller/BaseController.cs')
-rw-r--r-- | Ryujinx.HLE/Input/Controller/BaseController.cs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/Ryujinx.HLE/Input/Controller/BaseController.cs b/Ryujinx.HLE/Input/Controller/BaseController.cs new file mode 100644 index 00000000..dfd54a83 --- /dev/null +++ b/Ryujinx.HLE/Input/Controller/BaseController.cs @@ -0,0 +1,142 @@ +using static Ryujinx.HLE.Input.Hid; + +namespace Ryujinx.HLE.Input +{ + public abstract class BaseController : IHidDevice + { + protected ControllerStatus HidControllerType; + protected ControllerId ControllerId; + + private long _currentLayoutOffset; + private long _mainLayoutOffset; + + protected long DeviceStateOffset => Offset + 0x4188; + + protected Switch Device { get; } + + public long Offset { get; private set; } + public bool Connected { get; protected set; } + + public ControllerHeader Header { get; private set; } + public ControllerStateHeader CurrentStateHeader { get; private set; } + public ControllerDeviceState DeviceState { get; private set; } + public ControllerLayouts CurrentLayout { get; private set; } + public ControllerState LastInputState { get; set; } + public ControllerConnectionState ConnectionState { get; protected set; } + + public BaseController(Switch device, ControllerStatus controllerType) + { + Device = device; + HidControllerType = controllerType; + } + + protected void Initialize( + bool isHalf, + (NpadColor left, NpadColor right) bodyColors, + (NpadColor left, NpadColor right) buttonColors, + ControllerColorDescription singleColorDesc = 0, + ControllerColorDescription splitColorDesc = 0, + NpadColor singleBodyColor = 0, + NpadColor singleButtonColor = 0 + ) + { + Header = new ControllerHeader() + { + IsJoyConHalf = isHalf ? 1 : 0, + LeftBodyColor = bodyColors.left, + LeftButtonColor = buttonColors.left, + RightBodyColor = bodyColors.right, + RightButtonColor = buttonColors.right, + Status = HidControllerType, + SingleBodyColor = singleBodyColor, + SingleButtonColor = singleButtonColor, + SplitColorDescription = splitColorDesc, + SingleColorDescription = singleColorDesc, + }; + + CurrentStateHeader = new ControllerStateHeader + { + EntryCount = HidEntryCount, + MaxEntryCount = HidEntryCount - 1, + CurrentEntryIndex = -1 + }; + + DeviceState = new ControllerDeviceState() + { + PowerInfo0BatteryState = BatteryState.Percent100, + PowerInfo1BatteryState = BatteryState.Percent100, + PowerInfo2BatteryState = BatteryState.Percent100, + DeviceType = ControllerDeviceType.NPadLeftController | ControllerDeviceType.NPadRightController, + DeviceFlags = DeviceFlags.PowerInfo0Connected + | DeviceFlags.PowerInfo1Connected + | DeviceFlags.PowerInfo2Connected + }; + + LastInputState = new ControllerState() + { + SamplesTimestamp = -1, + SamplesTimestamp2 = -1 + }; + } + + public virtual void Connect(ControllerId controllerId) + { + ControllerId = controllerId; + + Offset = Device.Hid.HidPosition + HidControllersOffset + (int)controllerId * HidControllerSize; + + _mainLayoutOffset = Offset + HidControllerHeaderSize + + ((int)ControllerLayouts.Main * HidControllerLayoutsSize); + + Device.Memory.FillWithZeros(Offset, 0x5000); + Device.Memory.WriteStruct(Offset, Header); + Device.Memory.WriteStruct(DeviceStateOffset, DeviceState); + + Connected = true; + } + + public void SetLayout(ControllerLayouts controllerLayout) + { + CurrentLayout = controllerLayout; + + _currentLayoutOffset = Offset + HidControllerHeaderSize + + ((int)controllerLayout * HidControllerLayoutsSize); + } + + public void SendInput( + ControllerButtons buttons, + JoystickPosition leftStick, + JoystickPosition rightStick) + { + ControllerState currentInput = new ControllerState() + { + SamplesTimestamp = (long)LastInputState.SamplesTimestamp + 1, + SamplesTimestamp2 = (long)LastInputState.SamplesTimestamp + 1, + ButtonState = buttons, + ConnectionState = ConnectionState, + LeftStick = leftStick, + RightStick = rightStick + }; + + ControllerStateHeader newInputStateHeader = new ControllerStateHeader + { + EntryCount = HidEntryCount, + MaxEntryCount = HidEntryCount - 1, + CurrentEntryIndex = (CurrentStateHeader.CurrentEntryIndex + 1) % HidEntryCount, + Timestamp = GetTimestamp(), + }; + + Device.Memory.WriteStruct(_currentLayoutOffset, newInputStateHeader); + Device.Memory.WriteStruct(_mainLayoutOffset, newInputStateHeader); + + long currentInputStateOffset = HidControllersLayoutHeaderSize + + newInputStateHeader.CurrentEntryIndex * HidControllersInputEntrySize; + + Device.Memory.WriteStruct(_currentLayoutOffset + currentInputStateOffset, currentInput); + Device.Memory.WriteStruct(_mainLayoutOffset + currentInputStateOffset, currentInput); + + LastInputState = currentInput; + CurrentStateHeader = newInputStateHeader; + } + } +} |