Allow multiple hid shared memory locations

This commit is contained in:
gdkchan 2018-03-05 02:09:52 -03:00
parent 344fc8a55d
commit 73cc30cc80
4 changed files with 132 additions and 125 deletions

View file

@ -1,4 +1,6 @@
using ChocolArm64.Memory;
using Ryujinx.Core.OsHle.Handles;
using System;
using System.Diagnostics;
namespace Ryujinx.Core.Input
@ -60,33 +62,65 @@ namespace Ryujinx.Core.Input
private const int HidEntryCount = 17;
private long SharedMemOffset;
private object ShMemLock;
private Switch Ns;
private long[] ShMemPositions;
public Hid(Switch Ns)
private IntPtr Ram;
public Hid(IntPtr Ram)
{
this.Ns = Ns;
this.Ram = Ram;
ShMemLock = new object();
ShMemPositions = new long[0];
}
public void Init(long HidOffset)
internal void ShMemMap(object sender, EventArgs e)
{
SharedMemOffset = HidOffset;
HSharedMem SharedMem = (HSharedMem)sender;
lock (ShMemLock)
{
ShMemPositions = SharedMem.GetVirtualPositions();
long BasePosition = ShMemPositions[ShMemPositions.Length - 1];
Logging.Info($"HID shared memory successfully mapped to 0x{BasePosition:x16}!");
Init(BasePosition);
}
}
internal void ShMemUnmap(object sender, EventArgs e)
{
HSharedMem SharedMem = (HSharedMem)sender;
lock (ShMemLock)
{
ShMemPositions = SharedMem.GetVirtualPositions();
}
}
private void Init(long BasePosition)
{
InitializeJoyconPair(
BasePosition,
JoyConColor.Body_Neon_Red,
JoyConColor.Buttons_Neon_Red,
JoyConColor.Body_Neon_Blue,
JoyConColor.Buttons_Neon_Blue);
}
public void InitializeJoyconPair(
private void InitializeJoyconPair(
long BasePosition,
JoyConColor LeftColorBody,
JoyConColor LeftColorButtons,
JoyConColor RightColorBody,
JoyConColor RightColorButtons)
{
long BaseControllerOffset = HidControllersOffset + 8 * HidControllerSize;
long BaseControllerOffset = BasePosition + HidControllersOffset + 8 * HidControllerSize;
HidControllerType Type =
HidControllerType.ControllerType_Handheld |
@ -125,115 +159,123 @@ namespace Ryujinx.Core.Input
HidJoystickPosition LeftStick,
HidJoystickPosition RightStick)
{
long ControllerOffset = HidControllersOffset + (int)ControllerId * HidControllerSize;
lock (ShMemLock)
{
foreach (long Position in ShMemPositions)
{
long ControllerOffset = Position + HidControllersOffset;
ControllerOffset += HidControllerHeaderSize;
ControllerOffset += (int)ControllerId * HidControllerSize;
ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize;
ControllerOffset += HidControllerHeaderSize;
long LastEntry = ReadInt64(ControllerOffset + 0x10);
ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize;
long CurrEntry = (LastEntry + 1) % HidEntryCount;
long LastEntry = ReadInt64(ControllerOffset + 0x10);
long Timestamp = Stopwatch.GetTimestamp();
long CurrEntry = (LastEntry + 1) % HidEntryCount;
WriteInt64(ControllerOffset + 0x0, Timestamp);
WriteInt64(ControllerOffset + 0x8, HidEntryCount);
WriteInt64(ControllerOffset + 0x10, CurrEntry);
WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1);
long Timestamp = Stopwatch.GetTimestamp();
ControllerOffset += HidControllersLayoutHeaderSize;
WriteInt64(ControllerOffset + 0x0, Timestamp);
WriteInt64(ControllerOffset + 0x8, HidEntryCount);
WriteInt64(ControllerOffset + 0x10, CurrEntry);
WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1);
ControllerOffset += CurrEntry * HidControllersInputEntrySize;
ControllerOffset += HidControllersLayoutHeaderSize;
WriteInt64(ControllerOffset + 0x0, Timestamp);
WriteInt64(ControllerOffset + 0x8, Timestamp);
ControllerOffset += CurrEntry * HidControllersInputEntrySize;
WriteInt64(ControllerOffset + 0x10, (uint)Buttons);
WriteInt64(ControllerOffset + 0x0, Timestamp);
WriteInt64(ControllerOffset + 0x8, Timestamp);
WriteInt32(ControllerOffset + 0x18, LeftStick.DX);
WriteInt32(ControllerOffset + 0x1c, LeftStick.DY);
WriteInt64(ControllerOffset + 0x10, (uint)Buttons);
WriteInt64(ControllerOffset + 0x20, RightStick.DX);
WriteInt64(ControllerOffset + 0x24, RightStick.DY);
WriteInt32(ControllerOffset + 0x18, LeftStick.DX);
WriteInt32(ControllerOffset + 0x1c, LeftStick.DY);
WriteInt64(ControllerOffset + 0x28,
(uint)HidControllerConnState.Controller_State_Connected |
(uint)HidControllerConnState.Controller_State_Wired);
WriteInt64(ControllerOffset + 0x20, RightStick.DX);
WriteInt64(ControllerOffset + 0x24, RightStick.DY);
WriteInt64(ControllerOffset + 0x28,
(uint)HidControllerConnState.Controller_State_Connected |
(uint)HidControllerConnState.Controller_State_Wired);
}
}
}
public void SetTouchPoints(params HidTouchPoint[] Points)
{
long LastEntry = ReadInt64(HidTouchScreenOffset + 0x10);
long CurrEntry = (LastEntry + 1) % HidEntryCount;
long Timestamp = Stopwatch.GetTimestamp();
WriteInt64(HidTouchScreenOffset + 0x0, Timestamp);
WriteInt64(HidTouchScreenOffset + 0x8, HidEntryCount);
WriteInt64(HidTouchScreenOffset + 0x10, CurrEntry);
WriteInt64(HidTouchScreenOffset + 0x18, HidEntryCount - 1);
WriteInt64(HidTouchScreenOffset + 0x20, Timestamp);
long TouchEntryOffset = HidTouchScreenOffset + HidTouchHeaderSize;
long LastEntryOffset = TouchEntryOffset + LastEntry * HidTouchEntrySize;
long LastTimestamp = ReadInt64(LastEntryOffset);
TouchEntryOffset += CurrEntry * HidTouchEntrySize;
WriteInt64(TouchEntryOffset + 0x0, LastTimestamp + 1);
WriteInt64(TouchEntryOffset + 0x8, Points.Length);
TouchEntryOffset += HidTouchEntryHeaderSize;
const int Padding = 0;
int Index = 0;
foreach (HidTouchPoint Point in Points)
lock (ShMemLock)
{
WriteInt64(TouchEntryOffset + 0x0, Timestamp);
WriteInt32(TouchEntryOffset + 0x8, Padding);
WriteInt32(TouchEntryOffset + 0xc, Index++);
WriteInt32(TouchEntryOffset + 0x10, Point.X);
WriteInt32(TouchEntryOffset + 0x14, Point.Y);
WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX);
WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY);
WriteInt32(TouchEntryOffset + 0x20, Point.Angle);
WriteInt32(TouchEntryOffset + 0x24, Padding);
foreach (long Position in ShMemPositions)
{
long TouchScreenOffset = Position + HidTouchScreenOffset;
TouchEntryOffset += HidTouchEntryTouchSize;
long LastEntry = ReadInt64(TouchScreenOffset + 0x10);
long CurrEntry = (LastEntry + 1) % HidEntryCount;
long Timestamp = ReadInt64(TouchScreenOffset) + 1;
WriteInt64(TouchScreenOffset + 0x0, Timestamp);
WriteInt64(TouchScreenOffset + 0x8, HidEntryCount);
WriteInt64(TouchScreenOffset + 0x10, CurrEntry);
WriteInt64(TouchScreenOffset + 0x18, HidEntryCount - 1);
WriteInt64(TouchScreenOffset + 0x20, Timestamp);
long TouchEntryOffset = TouchScreenOffset + HidTouchHeaderSize;
long LastEntryOffset = TouchEntryOffset + LastEntry * HidTouchEntrySize;
TouchEntryOffset += CurrEntry * HidTouchEntrySize;
WriteInt64(TouchEntryOffset + 0x0, Timestamp);
WriteInt64(TouchEntryOffset + 0x8, Points.Length);
TouchEntryOffset += HidTouchEntryHeaderSize;
const int Padding = 0;
int Index = 0;
foreach (HidTouchPoint Point in Points)
{
WriteInt64(TouchEntryOffset + 0x0, Timestamp);
WriteInt32(TouchEntryOffset + 0x8, Padding);
WriteInt32(TouchEntryOffset + 0xc, Index++);
WriteInt32(TouchEntryOffset + 0x10, Point.X);
WriteInt32(TouchEntryOffset + 0x14, Point.Y);
WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX);
WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY);
WriteInt32(TouchEntryOffset + 0x20, Point.Angle);
WriteInt32(TouchEntryOffset + 0x24, Padding);
TouchEntryOffset += HidTouchEntryTouchSize;
}
}
}
}
private unsafe long ReadInt64(long Position)
{
Position += SharedMemOffset;
if ((ulong)Position + 8 > AMemoryMgr.AddrSize) return 0;
return *((long*)((byte*)Ns.Ram + Position));
return *((long*)((byte*)Ram + Position));
}
private unsafe void WriteInt32(long Position, int Value)
{
Position += SharedMemOffset;
if ((ulong)Position + 4 > AMemoryMgr.AddrSize) return;
*((int*)((byte*)Ns.Ram + Position)) = Value;
*((int*)((byte*)Ram + Position)) = Value;
}
private unsafe void WriteInt64(long Position, long Value)
{
Position += SharedMemOffset;
if ((ulong)Position + 8 > AMemoryMgr.AddrSize) return;
*((long*)((byte*)Ns.Ram + Position)) = Value;
*((long*)((byte*)Ram + Position)) = Value;
}
}
}

View file

@ -7,8 +7,6 @@ namespace Ryujinx.Core.OsHle.Handles
{
private List<long> Positions;
public int PositionsCount => Positions.Count;
public EventHandler<EventArgs> MemoryMapped;
public EventHandler<EventArgs> MemoryUnmapped;
@ -37,34 +35,9 @@ namespace Ryujinx.Core.OsHle.Handles
}
}
public long GetVirtualPosition(int Index)
public long[] GetVirtualPositions()
{
lock (Positions)
{
if (Index < 0 || Index >= Positions.Count)
{
throw new ArgumentOutOfRangeException(nameof(Index));
}
return Positions[Index];
}
}
public bool TryGetLastVirtualPosition(out long Position)
{
lock (Positions)
{
if (Positions.Count > 0)
{
Position = Positions[Positions.Count - 1];
return true;
}
Position = 0;
return false;
}
return Positions.ToArray();
}
}
}

View file

@ -27,7 +27,7 @@ namespace Ryujinx.Core.OsHle
private ConcurrentDictionary<int, Process> Processes;
private HSharedMem HidSharedMem;
internal HSharedMem HidSharedMem;
private Switch Ns;
@ -49,8 +49,6 @@ namespace Ryujinx.Core.OsHle
HidSharedMem = new HSharedMem();
HidSharedMem.MemoryMapped += HidInit;
HidHandle = Handles.GenerateId(HidSharedMem);
FontHandle = Handles.GenerateId(new HSharedMem());
@ -166,17 +164,5 @@ namespace Ryujinx.Core.OsHle
Handles.Delete(Handle);
}
private void HidInit(object sender, EventArgs e)
{
HSharedMem SharedMem = (HSharedMem)sender;
if (SharedMem.TryGetLastVirtualPosition(out long Position))
{
Logging.Info($"HID shared memory successfully mapped to 0x{Position:x16}!");
Ns.Hid.Init(Position);
}
}
}
}

View file

@ -27,10 +27,16 @@ namespace Ryujinx.Core
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
Gpu = new NsGpu(Renderer);
VFs = new VirtualFs();
Hid = new Hid(this);
Os = new Horizon(this);
Hid = new Hid(Ram);
Os = new Horizon(this);
Os.HidSharedMem.MemoryMapped += Hid.ShMemMap;
Os.HidSharedMem.MemoryUnmapped += Hid.ShMemUnmap;
Settings = new SetSys();
}