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 +++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs (limited to 'Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs') 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(); + } + } + } +} -- cgit v1.2.3