diff options
| author | mageven <62494521+mageven@users.noreply.github.com> | 2020-04-03 05:40:02 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-03 11:10:02 +1100 |
| commit | 2365ddfc363e76ac1ac9d2e32ef9b36b85463431 (patch) | |
| tree | 408bdb4a35e4f625a69ddbd65f22e9f056f7ebec /Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs | |
| parent | 5b5239ab5b452f991d9fc4f8ad1f9a2880b8bad1 (diff) | |
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
Diffstat (limited to 'Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs | 114 |
1 files changed, 114 insertions, 0 deletions
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>(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>()) + { + ControllerSupportArg arg = IApplet.ReadStruct<ControllerSupportArg>(controllerSupportArg); + argHeader = arg.Header; + // Read enable text here? + } + else + { + Logger.PrintStub(LogClass.ServiceHid, $"Unknown revision of ControllerSupportArg."); + + argHeader = IApplet.ReadStruct<ControllerSupportArgHeader>(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<ControllerSupportResultInfo>()))); + + 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(); + } + } + } +} |
