diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Applets/Controller')
6 files changed, 171 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(); + } + } + } +} 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 |
