aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.HLE/HOS/Services/Mm
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.HLE/HOS/Services/Mm
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Services/Mm')
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs196
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaOperationType.cs10
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaSession.cs24
3 files changed, 230 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs b/src/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs
new file mode 100644
index 00000000..fac42555
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs
@@ -0,0 +1,196 @@
+using Ryujinx.Common.Logging;
+using Ryujinx.HLE.HOS.Services.Mm.Types;
+using System.Collections.Generic;
+
+namespace Ryujinx.HLE.HOS.Services.Mm
+{
+ [Service("mm:u")]
+ class IRequest : IpcService
+ {
+ private static object _sessionListLock = new object();
+ private static List<MultiMediaSession> _sessionList = new List<MultiMediaSession>();
+
+ private static uint _uniqueId = 1;
+
+ public IRequest(ServiceCtx context) { }
+
+ [CommandCmif(0)]
+ // InitializeOld(u32, u32, u32)
+ public ResultCode InitializeOld(ServiceCtx context)
+ {
+ MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
+ int fgmId = context.RequestData.ReadInt32();
+ bool isAutoClearEvent = context.RequestData.ReadInt32() != 0;
+
+ Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType, fgmId, isAutoClearEvent });
+
+ Register(operationType, fgmId, isAutoClearEvent);
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(1)]
+ // FinalizeOld(u32)
+ public ResultCode FinalizeOld(ServiceCtx context)
+ {
+ MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
+
+ Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType });
+
+ lock (_sessionListLock)
+ {
+ _sessionList.Remove(GetSessionByType(operationType));
+ }
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(2)]
+ // SetAndWaitOld(u32, u32, u32)
+ public ResultCode SetAndWaitOld(ServiceCtx context)
+ {
+ MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
+ uint frequenceHz = context.RequestData.ReadUInt32();
+ int timeout = context.RequestData.ReadInt32();
+
+ Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType, frequenceHz, timeout });
+
+ lock (_sessionListLock)
+ {
+ GetSessionByType(operationType)?.SetAndWait(frequenceHz, timeout);
+ }
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(3)]
+ // GetOld(u32) -> u32
+ public ResultCode GetOld(ServiceCtx context)
+ {
+ MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
+
+ Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType });
+
+ lock (_sessionListLock)
+ {
+ MultiMediaSession session = GetSessionByType(operationType);
+
+ uint currentValue = session == null ? 0 : session.CurrentValue;
+
+ context.ResponseData.Write(currentValue);
+ }
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(4)]
+ // Initialize(u32, u32, u32) -> u32
+ public ResultCode Initialize(ServiceCtx context)
+ {
+ MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
+ int fgmId = context.RequestData.ReadInt32();
+ bool isAutoClearEvent = context.RequestData.ReadInt32() != 0;
+
+ Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType, fgmId, isAutoClearEvent });
+
+ uint id = Register(operationType, fgmId, isAutoClearEvent);
+
+ context.ResponseData.Write(id);
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(5)]
+ // Finalize(u32)
+ public ResultCode Finalize(ServiceCtx context)
+ {
+ uint id = context.RequestData.ReadUInt32();
+
+ Logger.Stub?.PrintStub(LogClass.ServiceMm, new { id });
+
+ lock (_sessionListLock)
+ {
+ _sessionList.Remove(GetSessionById(id));
+ }
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(6)]
+ // SetAndWait(u32, u32, u32)
+ public ResultCode SetAndWait(ServiceCtx context)
+ {
+ uint id = context.RequestData.ReadUInt32();
+ uint frequenceHz = context.RequestData.ReadUInt32();
+ int timeout = context.RequestData.ReadInt32();
+
+ Logger.Stub?.PrintStub(LogClass.ServiceMm, new { id, frequenceHz, timeout });
+
+ lock (_sessionListLock)
+ {
+ GetSessionById(id)?.SetAndWait(frequenceHz, timeout);
+ }
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(7)]
+ // Get(u32) -> u32
+ public ResultCode Get(ServiceCtx context)
+ {
+ uint id = context.RequestData.ReadUInt32();
+
+ Logger.Stub?.PrintStub(LogClass.ServiceMm, new { id });
+
+ lock (_sessionListLock)
+ {
+ MultiMediaSession session = GetSessionById(id);
+
+ uint currentValue = session == null ? 0 : session.CurrentValue;
+
+ context.ResponseData.Write(currentValue);
+ }
+
+ return ResultCode.Success;
+ }
+
+ private MultiMediaSession GetSessionById(uint id)
+ {
+ foreach (MultiMediaSession session in _sessionList)
+ {
+ if (session.Id == id)
+ {
+ return session;
+ }
+ }
+
+ return null;
+ }
+
+ private MultiMediaSession GetSessionByType(MultiMediaOperationType type)
+ {
+ foreach (MultiMediaSession session in _sessionList)
+ {
+ if (session.Type == type)
+ {
+ return session;
+ }
+ }
+
+ return null;
+ }
+
+ private uint Register(MultiMediaOperationType type, int fgmId, bool isAutoClearEvent)
+ {
+ lock (_sessionListLock)
+ {
+ // Nintendo ignore the fgm id as the other interfaces were deprecated.
+ MultiMediaSession session = new MultiMediaSession(_uniqueId++, type, isAutoClearEvent);
+
+ _sessionList.Add(session);
+
+ return session.Id;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaOperationType.cs b/src/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaOperationType.cs
new file mode 100644
index 00000000..2742af6c
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaOperationType.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Services.Mm.Types
+{
+ enum MultiMediaOperationType : uint
+ {
+ Ram = 2,
+ NvEnc = 5,
+ NvDec = 6,
+ NvJpg = 7
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaSession.cs b/src/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaSession.cs
new file mode 100644
index 00000000..a6723eca
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Mm/Types/MultiMediaSession.cs
@@ -0,0 +1,24 @@
+namespace Ryujinx.HLE.HOS.Services.Mm.Types
+{
+ class MultiMediaSession
+ {
+ public MultiMediaOperationType Type { get; }
+
+ public bool IsAutoClearEvent { get; }
+ public uint Id { get; }
+ public uint CurrentValue { get; private set; }
+
+ public MultiMediaSession(uint id, MultiMediaOperationType type, bool isAutoClearEvent)
+ {
+ Type = type;
+ Id = id;
+ IsAutoClearEvent = isAutoClearEvent;
+ CurrentValue = 0;
+ }
+
+ public void SetAndWait(uint value, int timeout)
+ {
+ CurrentValue = value;
+ }
+ }
+}