diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Mm/IRequest.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Services/Mm/IRequest.cs | 141 |
1 files changed, 118 insertions, 23 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs b/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs index cdd47295..f2891497 100644 --- a/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs +++ b/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs @@ -1,21 +1,30 @@ 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 { - public IRequest(ServiceCtx context) { } + private static object _sessionListLock = new object(); + private static List<MultiMediaSession> _sessionList = new List<MultiMediaSession>(); + + private static uint _uniqueId = 1; + + public IRequest(ServiceCtx context) {} [Command(0)] // InitializeOld(u32, u32, u32) public ResultCode InitializeOld(ServiceCtx context) { - int unknown0 = context.RequestData.ReadInt32(); - int unknown1 = context.RequestData.ReadInt32(); - int unknown2 = context.RequestData.ReadInt32(); + MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32(); + int fgmId = context.RequestData.ReadInt32(); + bool isAutoClearEvent = context.RequestData.ReadInt32() != 0; - Logger.PrintStub(LogClass.ServiceMm, new { unknown0, unknown1, unknown2 }); + Logger.PrintStub(LogClass.ServiceMm, new { operationType, fgmId, isAutoClearEvent }); + + Register(operationType, fgmId, isAutoClearEvent); return ResultCode.Success; } @@ -24,7 +33,14 @@ namespace Ryujinx.HLE.HOS.Services.Mm // FinalizeOld(u32) public ResultCode FinalizeOld(ServiceCtx context) { - Logger.PrintStub(LogClass.ServiceMm); + MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32(); + + Logger.PrintStub(LogClass.ServiceMm, new { operationType }); + + lock (_sessionListLock) + { + _sessionList.Remove(GetSessionByType(operationType)); + } return ResultCode.Success; } @@ -33,11 +49,17 @@ namespace Ryujinx.HLE.HOS.Services.Mm // SetAndWaitOld(u32, u32, u32) public ResultCode SetAndWaitOld(ServiceCtx context) { - int unknown0 = context.RequestData.ReadInt32(); - int unknown1 = context.RequestData.ReadInt32(); - int unknown2 = context.RequestData.ReadInt32(); + MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32(); + uint value = context.RequestData.ReadUInt32(); + int timeout = context.RequestData.ReadInt32(); + + Logger.PrintStub(LogClass.ServiceMm, new { operationType, value, timeout }); + + lock (_sessionListLock) + { + GetSessionByType(operationType)?.SetAndWait(value, timeout); + } - Logger.PrintStub(LogClass.ServiceMm, new { unknown0, unknown1, unknown2 }); return ResultCode.Success; } @@ -45,20 +67,35 @@ namespace Ryujinx.HLE.HOS.Services.Mm // GetOld(u32) -> u32 public ResultCode GetOld(ServiceCtx context) { - int unknown0 = context.RequestData.ReadInt32(); + MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32(); - Logger.PrintStub(LogClass.ServiceMm, new { unknown0 }); + Logger.PrintStub(LogClass.ServiceMm, new { operationType }); - context.ResponseData.Write(0); + lock (_sessionListLock) + { + MultiMediaSession session = GetSessionByType(operationType); + + uint currentValue = session == null ? 0 : session.CurrentValue; + + context.ResponseData.Write(currentValue); + } return ResultCode.Success; } [Command(4)] - // Initialize() + // Initialize(u32, u32, u32) -> u32 public ResultCode Initialize(ServiceCtx context) { - Logger.PrintStub(LogClass.ServiceMm); + MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32(); + int fgmId = context.RequestData.ReadInt32(); + bool isAutoClearEvent = context.RequestData.ReadInt32() != 0; + + Logger.PrintStub(LogClass.ServiceMm, new { operationType, fgmId, isAutoClearEvent }); + + uint id = Register(operationType, fgmId, isAutoClearEvent); + + context.ResponseData.Write(id); return ResultCode.Success; } @@ -67,7 +104,14 @@ namespace Ryujinx.HLE.HOS.Services.Mm // Finalize(u32) public ResultCode Finalize(ServiceCtx context) { - Logger.PrintStub(LogClass.ServiceMm); + uint id = context.RequestData.ReadUInt32(); + + Logger.PrintStub(LogClass.ServiceMm, new { id }); + + lock (_sessionListLock) + { + _sessionList.Remove(GetSessionById(id)); + } return ResultCode.Success; } @@ -76,11 +120,16 @@ namespace Ryujinx.HLE.HOS.Services.Mm // SetAndWait(u32, u32, u32) public ResultCode SetAndWait(ServiceCtx context) { - int unknown0 = context.RequestData.ReadInt32(); - int unknown1 = context.RequestData.ReadInt32(); - int unknown2 = context.RequestData.ReadInt32(); + uint id = context.RequestData.ReadUInt32(); + uint value = context.RequestData.ReadUInt32(); + int timeout = context.RequestData.ReadInt32(); - Logger.PrintStub(LogClass.ServiceMm, new { unknown0, unknown1, unknown2 }); + Logger.PrintStub(LogClass.ServiceMm, new { id, value, timeout }); + + lock (_sessionListLock) + { + GetSessionById(id)?.SetAndWait(value, timeout); + } return ResultCode.Success; } @@ -89,13 +138,59 @@ namespace Ryujinx.HLE.HOS.Services.Mm // Get(u32) -> u32 public ResultCode Get(ServiceCtx context) { - int unknown0 = context.RequestData.ReadInt32(); + uint id = context.RequestData.ReadUInt32(); + + Logger.PrintStub(LogClass.ServiceMm, new { id }); - Logger.PrintStub(LogClass.ServiceMm, new { unknown0 }); + lock (_sessionListLock) + { + MultiMediaSession session = GetSessionById(id); - context.ResponseData.Write(0); + 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 |
