ryujinx/Ryujinx.HLE/Input/Hid.cs

219 lines
7.2 KiB
C#
Raw Normal View History

using Ryujinx.Common;
using Ryujinx.Configuration.Hid;
using Ryujinx.HLE.HOS;
using System;
namespace Ryujinx.HLE.Input
{
public partial class Hid
{
private Switch _device;
private long _touchScreenOffset;
private long _touchEntriesOffset;
private long _keyboardOffset;
private TouchHeader _currentTouchHeader;
private KeyboardHeader _currentKeyboardHeader;
private KeyboardEntry _currentKeyboardEntry;
public BaseController PrimaryController { get; private set; }
internal long HidPosition;
public Hid(Switch device, long hidPosition)
{
_device = device;
HidPosition = hidPosition;
device.Memory.FillWithZeros(hidPosition, Horizon.HidSize);
_currentTouchHeader = new TouchHeader()
{
CurrentEntryIndex = -1,
};
_currentKeyboardHeader = new KeyboardHeader()
{
CurrentEntryIndex = -1,
};
_currentKeyboardEntry = new KeyboardEntry()
{
SamplesTimestamp = -1,
SamplesTimestamp2 = -1
};
_touchScreenOffset = HidPosition + HidTouchScreenOffset;
_touchEntriesOffset = _touchScreenOffset + HidTouchHeaderSize;
_keyboardOffset = HidPosition + HidKeyboardOffset;
}
private static ControllerStatus ConvertControllerTypeToState(ControllerType controllerType)
{
switch (controllerType)
{
case ControllerType.Handheld: return ControllerStatus.Handheld;
case ControllerType.NpadLeft: return ControllerStatus.NpadLeft;
case ControllerType.NpadRight: return ControllerStatus.NpadRight;
case ControllerType.NpadPair: return ControllerStatus.NpadPair;
case ControllerType.ProController: return ControllerStatus.ProController;
default: throw new NotImplementedException();
}
}
public void InitializePrimaryController(ControllerType controllerType)
{
ControllerId controllerId = controllerType == ControllerType.Handheld ?
ControllerId.ControllerHandheld : ControllerId.ControllerPlayer1;
if (controllerType == ControllerType.ProController)
{
PrimaryController = new ProController(_device, NpadColor.Black, NpadColor.Black);
}
else
{
PrimaryController = new NpadController(ConvertControllerTypeToState(controllerType),
_device,
(NpadColor.BodyNeonRed, NpadColor.BodyNeonRed),
(NpadColor.ButtonsNeonBlue, NpadColor.ButtonsNeonBlue));
}
PrimaryController.Connect(controllerId);
}
public ControllerButtons UpdateStickButtons(
JoystickPosition leftStick,
JoystickPosition rightStick)
{
ControllerButtons result = 0;
if (rightStick.Dx < 0)
{
result |= ControllerButtons.RStickLeft;
}
if (rightStick.Dx > 0)
{
result |= ControllerButtons.RStickRight;
}
if (rightStick.Dy < 0)
{
result |= ControllerButtons.RStickDown;
}
if (rightStick.Dy > 0)
{
result |= ControllerButtons.RStickUp;
}
if (leftStick.Dx < 0)
{
result |= ControllerButtons.LStickLeft;
}
if (leftStick.Dx > 0)
{
result |= ControllerButtons.LStickRight;
}
if (leftStick.Dy < 0)
{
result |= ControllerButtons.LStickDown;
}
if (leftStick.Dy > 0)
{
result |= ControllerButtons.LStickUp;
}
return result;
}
public void SetTouchPoints(params TouchPoint[] points)
{
long timestamp = GetTimestamp();
long sampleCounter = _currentTouchHeader.SamplesTimestamp + 1;
var newTouchHeader = new TouchHeader
{
CurrentEntryIndex = (_currentTouchHeader.CurrentEntryIndex + 1) % HidEntryCount,
EntryCount = HidEntryCount,
MaxEntries = HidEntryCount - 1,
SamplesTimestamp = sampleCounter,
Timestamp = timestamp,
};
long currentTouchEntryOffset = _touchEntriesOffset + newTouchHeader.CurrentEntryIndex * HidTouchEntrySize;
TouchEntry touchEntry = new TouchEntry()
{
SamplesTimestamp = sampleCounter,
TouchCount = points.Length
};
_device.Memory.WriteStruct(currentTouchEntryOffset, touchEntry);
currentTouchEntryOffset += HidTouchEntryHeaderSize;
for (int i = 0; i < points.Length; i++)
{
TouchData touch = new TouchData()
{
Angle = points[i].Angle,
DiameterX = points[i].DiameterX,
DiameterY = points[i].DiameterY,
Index = i,
SampleTimestamp = sampleCounter,
X = points[i].X,
Y = points[i].Y
};
_device.Memory.WriteStruct(currentTouchEntryOffset, touch);
currentTouchEntryOffset += HidTouchEntryTouchSize;
}
_device.Memory.WriteStruct(_touchScreenOffset, newTouchHeader);
_currentTouchHeader = newTouchHeader;
}
public unsafe void WriteKeyboard(Keyboard keyboard)
{
long timestamp = GetTimestamp();
var newKeyboardHeader = new KeyboardHeader()
{
CurrentEntryIndex = (_currentKeyboardHeader.CurrentEntryIndex + 1) % HidEntryCount,
EntryCount = HidEntryCount,
MaxEntries = HidEntryCount - 1,
Timestamp = timestamp,
};
_device.Memory.WriteStruct(_keyboardOffset, newKeyboardHeader);
long keyboardEntryOffset = _keyboardOffset + HidKeyboardHeaderSize;
keyboardEntryOffset += newKeyboardHeader.CurrentEntryIndex * HidKeyboardEntrySize;
var newkeyboardEntry = new KeyboardEntry()
{
SamplesTimestamp = _currentKeyboardEntry.SamplesTimestamp + 1,
SamplesTimestamp2 = _currentKeyboardEntry.SamplesTimestamp2 + 1,
Keys = keyboard.Keys,
Modifier = keyboard.Modifier,
};
_device.Memory.WriteStruct(keyboardEntryOffset, newkeyboardEntry);
_currentKeyboardEntry = newkeyboardEntry;
_currentKeyboardHeader = newKeyboardHeader;
}
internal static long GetTimestamp()
{
return PerformanceCounter.ElapsedMilliseconds * 19200;
}
}
}