diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.HLE/HOS/Services/Mm | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Services/Mm')
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; + } + } +} |
