aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/Mm/IRequest.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Mm/IRequest.cs')
-rw-r--r--Ryujinx.HLE/HOS/Services/Mm/IRequest.cs141
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