From 2365ddfc363e76ac1ac9d2e32ef9b36b85463431 Mon Sep 17 00:00:00 2001 From: mageven <62494521+mageven@users.noreply.github.com> Date: Fri, 3 Apr 2020 05:40:02 +0530 Subject: HID SharedMem Rework (#1003) * Delete old HLE.Input * Add new HLE Input. git shows Hid.cs as modified because of the same name. It is new. * Change HID Service * Change Ryujinx UI to reflect new Input * Add basic ControllerApplet * Add DebugPad Should fix Kirby Star Allies * Address Ac_K's comments * Moved all of HLE.Input to Services.Hid * Separated all structs and enums each to a file * Removed vars * Made some naming changes to align with switchbrew * Added official joycon colors As an aside, fixed a mistake in touchscreen headers and added checks to important SharedMem structs at init time. * Further address Ac_K's comments * Addressed gdkchan's and some more Ac_K's comments * Address AcK's review comments * Address AcK's second review comments * Replace missed Marshal.SizeOf and address gdkchan's comments --- .../HOS/Applets/Controller/ControllerApplet.cs | 114 +++++++++++++++++++++ .../HOS/Applets/Controller/ControllerSupportArg.cs | 11 ++ .../Controller/ControllerSupportArgHeader.cs | 13 +++ .../Controller/ControllerSupportArgPrivate.cs | 14 +++ .../Applets/Controller/ControllerSupportMode.cs | 9 ++ .../Controller/ControllerSupportResultInfo.cs | 10 ++ 6 files changed, 171 insertions(+) create mode 100644 Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs create mode 100644 Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArg.cs create mode 100644 Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgHeader.cs create mode 100644 Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgPrivate.cs create mode 100644 Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportMode.cs create mode 100644 Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportResultInfo.cs (limited to 'Ryujinx.HLE/HOS/Applets/Controller') diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs new file mode 100644 index 00000000..5bfffdb2 --- /dev/null +++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs @@ -0,0 +1,114 @@ +using System; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Ryujinx.Common.Logging; +using Ryujinx.HLE.HOS.Services.Hid; +using Ryujinx.HLE.HOS.Services.Am.AppletAE; + +using static Ryujinx.HLE.HOS.Services.Hid.HidServer.HidUtils; + +namespace Ryujinx.HLE.HOS.Applets +{ + internal class ControllerApplet : IApplet + { + private Horizon _system; + + private AppletSession _normalSession; + + public event EventHandler AppletStateChanged; + + public ControllerApplet(Horizon system) + { + _system = system; + } + + unsafe public ResultCode Start(AppletSession normalSession, + AppletSession interactiveSession) + { + _normalSession = normalSession; + + byte[] launchParams = _normalSession.Pop(); + byte[] controllerSupportArgPrivate = _normalSession.Pop(); + ControllerSupportArgPrivate privateArg = IApplet.ReadStruct(controllerSupportArgPrivate); + + Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet ArgPriv {privateArg.PrivateSize} {privateArg.ArgSize} {privateArg.Mode}" + + $"HoldType:{(NpadJoyHoldType)privateArg.NpadJoyHoldType} StyleSets:{(ControllerType)privateArg.NpadStyleSet}"); + + if (privateArg.Mode != ControllerSupportMode.ShowControllerSupport) + { + _normalSession.Push(BuildResponse()); // Dummy response for other modes + AppletStateChanged?.Invoke(this, null); + + return ResultCode.Success; + } + + byte[] controllerSupportArg = _normalSession.Pop(); + + ControllerSupportArgHeader argHeader; + + if (privateArg.ArgSize == Marshal.SizeOf()) + { + ControllerSupportArg arg = IApplet.ReadStruct(controllerSupportArg); + argHeader = arg.Header; + // Read enable text here? + } + else + { + Logger.PrintStub(LogClass.ServiceHid, $"Unknown revision of ControllerSupportArg."); + + argHeader = IApplet.ReadStruct(controllerSupportArg); // Read just the header + } + + Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet Arg {argHeader.PlayerCountMin} {argHeader.PlayerCountMax} {argHeader.EnableTakeOverConnection} {argHeader.EnableSingleMode}"); + + // Currently, the only purpose of this applet is to help + // choose the primary input controller for the game + // TODO: Ideally should hook back to HID.Controller. When applet is called, can choose appropriate controller and attach to appropriate id. + if (argHeader.PlayerCountMin > 1) + { + Logger.PrintWarning(LogClass.ServiceHid, "More than one controller was requested."); + } + + ControllerSupportResultInfo result = new ControllerSupportResultInfo + { + PlayerCount = 1, + SelectedId = (uint)GetNpadIdTypeFromIndex(_system.Device.Hid.Npads.PrimaryController) + }; + + Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet ReturnResult {result.PlayerCount} {result.SelectedId}"); + + _normalSession.Push(BuildResponse(result)); + AppletStateChanged?.Invoke(this, null); + + return ResultCode.Success; + } + + public ResultCode GetResult() + { + return ResultCode.Success; + } + + private byte[] BuildResponse(ControllerSupportResultInfo result) + { + using (MemoryStream stream = new MemoryStream()) + using (BinaryWriter writer = new BinaryWriter(stream)) + { + writer.Write(MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref result, Unsafe.SizeOf()))); + + return stream.ToArray(); + } + } + + private byte[] BuildResponse() + { + using (MemoryStream stream = new MemoryStream()) + using (BinaryWriter writer = new BinaryWriter(stream)) + { + writer.Write((ulong)ResultCode.Success); + + return stream.ToArray(); + } + } + } +} diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArg.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArg.cs new file mode 100644 index 00000000..62ebff30 --- /dev/null +++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArg.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.HLE.HOS.Applets +{ + // (8.0.0+ version) + unsafe struct ControllerSupportArg + { + public ControllerSupportArgHeader Header; + public fixed uint IdentificationColor[8]; + public byte EnableExplainText; + public fixed byte ExplainText[8 * 0x81]; + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgHeader.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgHeader.cs new file mode 100644 index 00000000..dfe26093 --- /dev/null +++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgHeader.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.HLE.HOS.Applets +{ + struct ControllerSupportArgHeader + { + public sbyte PlayerCountMin; + public sbyte PlayerCountMax; + public byte EnableTakeOverConnection; + public byte EnableLeftJustify; + public byte EnablePermitJoyDual; + public byte EnableSingleMode; + public byte EnableIdentificationColor; + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgPrivate.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgPrivate.cs new file mode 100644 index 00000000..2e393de4 --- /dev/null +++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportArgPrivate.cs @@ -0,0 +1,14 @@ +namespace Ryujinx.HLE.HOS.Applets +{ + struct ControllerSupportArgPrivate + { + public uint PrivateSize; + public uint ArgSize; + public byte Flag0; + public byte Flag1; + public ControllerSupportMode Mode; + public byte ControllerSupportCaller; + public uint NpadStyleSet; + public uint NpadJoyHoldType; + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportMode.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportMode.cs new file mode 100644 index 00000000..9496c1dd --- /dev/null +++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportMode.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Applets +{ + enum ControllerSupportMode : byte + { + ShowControllerSupport = 0, + ShowControllerStrapGuide = 1, + ShowControllerFirmwareUpdate = 2 + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportResultInfo.cs b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportResultInfo.cs new file mode 100644 index 00000000..4fcd37db --- /dev/null +++ b/Ryujinx.HLE/HOS/Applets/Controller/ControllerSupportResultInfo.cs @@ -0,0 +1,10 @@ +namespace Ryujinx.HLE.HOS.Applets +{ + unsafe struct ControllerSupportResultInfo + { + public sbyte PlayerCount; + fixed byte _padding[3]; + public uint SelectedId; + public uint Result; + } +} \ No newline at end of file -- cgit v1.2.3