|
@@ -11,35 +11,50 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
|
|
{
|
|
{
|
|
|
private IApplet _applet;
|
|
private IApplet _applet;
|
|
|
|
|
|
|
|
- private AppletFifo<byte[]> _inData;
|
|
|
|
|
- private AppletFifo<byte[]> _outData;
|
|
|
|
|
|
|
+ private AppletSession _normalSession;
|
|
|
|
|
+ private AppletSession _interactiveSession;
|
|
|
|
|
|
|
|
private KEvent _stateChangedEvent;
|
|
private KEvent _stateChangedEvent;
|
|
|
|
|
+ private KEvent _normalOutDataEvent;
|
|
|
|
|
+ private KEvent _interactiveOutDataEvent;
|
|
|
|
|
|
|
|
public ILibraryAppletAccessor(AppletId appletId, Horizon system)
|
|
public ILibraryAppletAccessor(AppletId appletId, Horizon system)
|
|
|
{
|
|
{
|
|
|
- _stateChangedEvent = new KEvent(system);
|
|
|
|
|
|
|
+ _stateChangedEvent = new KEvent(system);
|
|
|
|
|
+ _normalOutDataEvent = new KEvent(system);
|
|
|
|
|
+ _interactiveOutDataEvent = new KEvent(system);
|
|
|
|
|
|
|
|
- _applet = AppletManager.Create(appletId, system);
|
|
|
|
|
- _inData = new AppletFifo<byte[]>();
|
|
|
|
|
- _outData = new AppletFifo<byte[]>();
|
|
|
|
|
-
|
|
|
|
|
- _applet.AppletStateChanged += OnAppletStateChanged;
|
|
|
|
|
|
|
+ _applet = AppletManager.Create(appletId, system);
|
|
|
|
|
+
|
|
|
|
|
+ _normalSession = new AppletSession();
|
|
|
|
|
+ _interactiveSession = new AppletSession();
|
|
|
|
|
+
|
|
|
|
|
+ _applet.AppletStateChanged += OnAppletStateChanged;
|
|
|
|
|
+ _normalSession.DataAvailable += OnNormalOutData;
|
|
|
|
|
+ _interactiveSession.DataAvailable += OnInteractiveOutData;
|
|
|
|
|
|
|
|
Logger.PrintInfo(LogClass.ServiceAm, $"Applet '{appletId}' created.");
|
|
Logger.PrintInfo(LogClass.ServiceAm, $"Applet '{appletId}' created.");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void OnAppletStateChanged(object sender, EventArgs e)
|
|
private void OnAppletStateChanged(object sender, EventArgs e)
|
|
|
{
|
|
{
|
|
|
- _stateChangedEvent.ReadableEvent.Signal();
|
|
|
|
|
|
|
+ _stateChangedEvent.WritableEvent.Signal();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void OnNormalOutData(object sender, EventArgs e)
|
|
|
|
|
+ {
|
|
|
|
|
+ _normalOutDataEvent.WritableEvent.Signal();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void OnInteractiveOutData(object sender, EventArgs e)
|
|
|
|
|
+ {
|
|
|
|
|
+ _interactiveOutDataEvent.WritableEvent.Signal();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
[Command(0)]
|
|
[Command(0)]
|
|
|
// GetAppletStateChangedEvent() -> handle<copy>
|
|
// GetAppletStateChangedEvent() -> handle<copy>
|
|
|
public ResultCode GetAppletStateChangedEvent(ServiceCtx context)
|
|
public ResultCode GetAppletStateChangedEvent(ServiceCtx context)
|
|
|
{
|
|
{
|
|
|
- _stateChangedEvent.ReadableEvent.Signal();
|
|
|
|
|
-
|
|
|
|
|
if (context.Process.HandleTable.GenerateHandle(_stateChangedEvent.ReadableEvent, out int handle) != KernelResult.Success)
|
|
if (context.Process.HandleTable.GenerateHandle(_stateChangedEvent.ReadableEvent, out int handle) != KernelResult.Success)
|
|
|
{
|
|
{
|
|
|
throw new InvalidOperationException("Out of handles!");
|
|
throw new InvalidOperationException("Out of handles!");
|
|
@@ -54,7 +69,8 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
|
|
// Start()
|
|
// Start()
|
|
|
public ResultCode Start(ServiceCtx context)
|
|
public ResultCode Start(ServiceCtx context)
|
|
|
{
|
|
{
|
|
|
- return (ResultCode)_applet.Start(_inData, _outData);
|
|
|
|
|
|
|
+ return (ResultCode)_applet.Start(_normalSession.GetConsumer(),
|
|
|
|
|
+ _interactiveSession.GetConsumer());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
[Command(30)]
|
|
[Command(30)]
|
|
@@ -70,7 +86,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
|
|
{
|
|
{
|
|
|
IStorage data = GetObject<IStorage>(context, 0);
|
|
IStorage data = GetObject<IStorage>(context, 0);
|
|
|
|
|
|
|
|
- _inData.Push(data.Data);
|
|
|
|
|
|
|
+ _normalSession.Push(data.Data);
|
|
|
|
|
|
|
|
return ResultCode.Success;
|
|
return ResultCode.Success;
|
|
|
}
|
|
}
|
|
@@ -79,10 +95,70 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Lib
|
|
|
// PopOutData() -> object<nn::am::service::IStorage>
|
|
// PopOutData() -> object<nn::am::service::IStorage>
|
|
|
public ResultCode PopOutData(ServiceCtx context)
|
|
public ResultCode PopOutData(ServiceCtx context)
|
|
|
{
|
|
{
|
|
|
- byte[] data = _outData.Pop();
|
|
|
|
|
|
|
+ if(_normalSession.TryPop(out byte[] data))
|
|
|
|
|
+ {
|
|
|
|
|
+ MakeObject(context, new IStorage(data));
|
|
|
|
|
+
|
|
|
|
|
+ _normalOutDataEvent.WritableEvent.Clear();
|
|
|
|
|
+
|
|
|
|
|
+ return ResultCode.Success;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return ResultCode.NotAvailable;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ [Command(103)]
|
|
|
|
|
+ // PushInteractiveInData(object<nn::am::service::IStorage>)
|
|
|
|
|
+ public ResultCode PushInteractiveInData(ServiceCtx context)
|
|
|
|
|
+ {
|
|
|
|
|
+ IStorage data = GetObject<IStorage>(context, 0);
|
|
|
|
|
+
|
|
|
|
|
+ _interactiveSession.Push(data.Data);
|
|
|
|
|
+
|
|
|
|
|
+ return ResultCode.Success;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ [Command(104)]
|
|
|
|
|
+ // PopInteractiveOutData() -> object<nn::am::service::IStorage>
|
|
|
|
|
+ public ResultCode PopInteractiveOutData(ServiceCtx context)
|
|
|
|
|
+ {
|
|
|
|
|
+ if(_interactiveSession.TryPop(out byte[] data))
|
|
|
|
|
+ {
|
|
|
|
|
+ MakeObject(context, new IStorage(data));
|
|
|
|
|
+
|
|
|
|
|
+ _interactiveOutDataEvent.WritableEvent.Clear();
|
|
|
|
|
+
|
|
|
|
|
+ return ResultCode.Success;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return ResultCode.NotAvailable;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ [Command(105)]
|
|
|
|
|
+ // GetPopOutDataEvent() -> handle<copy>
|
|
|
|
|
+ public ResultCode GetPopOutDataEvent(ServiceCtx context)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (context.Process.HandleTable.GenerateHandle(_normalOutDataEvent.ReadableEvent, out int handle) != KernelResult.Success)
|
|
|
|
|
+ {
|
|
|
|
|
+ throw new InvalidOperationException("Out of handles!");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
|
|
|
|
|
+
|
|
|
|
|
+ return ResultCode.Success;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ [Command(106)]
|
|
|
|
|
+ // GetPopInteractiveOutDataEvent() -> handle<copy>
|
|
|
|
|
+ public ResultCode GetPopInteractiveOutDataEvent(ServiceCtx context)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (context.Process.HandleTable.GenerateHandle(_interactiveOutDataEvent.ReadableEvent, out int handle) != KernelResult.Success)
|
|
|
|
|
+ {
|
|
|
|
|
+ throw new InvalidOperationException("Out of handles!");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
|
|
|
|
|
|
|
|
- MakeObject(context, new IStorage(data));
|
|
|
|
|
-
|
|
|
|
|
return ResultCode.Success;
|
|
return ResultCode.Success;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|