diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index e152846e42..d308c082c5 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -31,6 +31,7 @@ namespace Ryujinx.HLE.HOS internal const int HidSize = 0x40000; internal const int FontSize = 0x1100000; internal const int IirsSize = 0x8000; + internal const int TimeSize = 0x1000; private const int MemoryBlockAllocatorSize = 0x2710; @@ -83,6 +84,7 @@ namespace Ryujinx.HLE.HOS internal KSharedMemory HidSharedMem { get; private set; } internal KSharedMemory FontSharedMem { get; private set; } internal KSharedMemory IirsSharedMem { get; private set; } + internal KSharedMemory TimeSharedMem { get; private set; } internal SharedFontManager Font { get; private set; } @@ -154,20 +156,24 @@ namespace Ryujinx.HLE.HOS ulong hidPa = region.Address; ulong fontPa = region.Address + HidSize; ulong iirsPa = region.Address + HidSize + FontSize; + ulong timePa = region.Address + HidSize + FontSize + IirsSize; HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase); KPageList hidPageList = new KPageList(); KPageList fontPageList = new KPageList(); KPageList iirsPageList = new KPageList(); + KPageList timePageList = new KPageList(); hidPageList .AddRange(hidPa, HidSize / KMemoryManager.PageSize); fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize); iirsPageList.AddRange(iirsPa, IirsSize / KMemoryManager.PageSize); + timePageList.AddRange(timePa, TimeSize / KMemoryManager.PageSize); HidSharedMem = new KSharedMemory(this, hidPageList, 0, 0, MemoryPermission.Read); FontSharedMem = new KSharedMemory(this, fontPageList, 0, 0, MemoryPermission.Read); IirsSharedMem = new KSharedMemory(this, iirsPageList, 0, 0, MemoryPermission.Read); + TimeSharedMem = new KSharedMemory(this, timePageList, 0, 0, MemoryPermission.Read); AppletState = new AppletStateMgr(this); diff --git a/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs b/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs index 7d900d2e53..dc2d7e8139 100644 --- a/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs +++ b/Ryujinx.HLE/HOS/Services/Am/ISelfController.cs @@ -17,27 +17,33 @@ namespace Ryujinx.HLE.HOS.Services.Am private int _idleTimeDetectionExtension; + private int _suspendedTickValue; + private KEvent _suspendedTickChangedEvent; + public ISelfController(Horizon system) { _commands = new Dictionary { - { 0, Exit }, - { 1, LockExit }, - { 2, UnlockExit }, - { 9, GetLibraryAppletLaunchableEvent }, - { 10, SetScreenShotPermission }, - { 11, SetOperationModeChangedNotification }, - { 12, SetPerformanceModeChangedNotification }, - { 13, SetFocusHandlingMode }, - { 14, SetRestartMessageEnabled }, - { 16, SetOutOfFocusSuspendingEnabled }, - { 19, SetScreenShotImageOrientation }, - { 50, SetHandlesRequestToDisplay }, - { 62, SetIdleTimeDetectionExtension }, - { 63, GetIdleTimeDetectionExtension } + { 0, Exit }, + { 1, LockExit }, + { 2, UnlockExit }, + { 9, GetLibraryAppletLaunchableEvent }, + { 10, SetScreenShotPermission }, + { 11, SetOperationModeChangedNotification }, + { 12, SetPerformanceModeChangedNotification }, + { 13, SetFocusHandlingMode }, + { 14, SetRestartMessageEnabled }, + { 16, SetOutOfFocusSuspendingEnabled }, + { 19, SetScreenShotImageOrientation }, + { 50, SetHandlesRequestToDisplay }, + { 62, SetIdleTimeDetectionExtension }, + { 63, GetIdleTimeDetectionExtension }, + { 90, GetAccumulatedSuspendedTickValue }, + { 91, GetAccumulatedSuspendedTickChangedEvent } }; - _launchableEvent = new KEvent(system); + _launchableEvent = new KEvent(system); + _suspendedTickChangedEvent = new KEvent(system); } public long Exit(ServiceCtx context) @@ -170,5 +176,30 @@ namespace Ryujinx.HLE.HOS.Services.Am return 0; } + + public long GetAccumulatedSuspendedTickValue(ServiceCtx context) + { + context.ResponseData.Write(_suspendedTickValue); + + Logger.PrintStub(LogClass.ServiceAm); + + return 0; + } + + public long GetAccumulatedSuspendedTickChangedEvent(ServiceCtx context) + { + _suspendedTickChangedEvent.ReadableEvent.Signal(); + + if (context.Process.HandleTable.GenerateHandle(_suspendedTickChangedEvent.ReadableEvent, out int handle) != KernelResult.Success) + { + throw new InvalidOperationException("Out of handles!"); + } + + context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle); + + Logger.PrintStub(LogClass.ServiceAm); + + return 0; + } } } diff --git a/Ryujinx.HLE/HOS/Services/Irs/IIrSensorServer.cs b/Ryujinx.HLE/HOS/Services/Irs/IIrSensorServer.cs index 500d5f1079..2f43a22e3d 100644 --- a/Ryujinx.HLE/HOS/Services/Irs/IIrSensorServer.cs +++ b/Ryujinx.HLE/HOS/Services/Irs/IIrSensorServer.cs @@ -1,8 +1,8 @@ using Ryujinx.Common.Logging; -using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Memory; +using Ryujinx.HLE.HOS.Kernel.Process; using System; using System.Collections.Generic; @@ -14,9 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.Irs public override IReadOnlyDictionary Commands => _commands; - private KSharedMemory _irsSharedMem; - - public IIrSensorServer(KSharedMemory irsSharedMem) + public IIrSensorServer() { _commands = new Dictionary { @@ -25,8 +23,6 @@ namespace Ryujinx.HLE.HOS.Services.Irs { 304, GetIrsensorSharedMemoryHandle }, { 311, GetNpadIrCameraHandle } }; - - _irsSharedMem = irsSharedMem; } // ActivateIrsensor(nn::applet::AppletResourceUserId, pid) @@ -52,9 +48,7 @@ namespace Ryujinx.HLE.HOS.Services.Irs // GetIrsensorSharedMemoryHandle(nn::applet::AppletResourceUserId, pid) -> handle public long GetIrsensorSharedMemoryHandle(ServiceCtx context) { - var handleTable = context.Process.HandleTable; - - if (handleTable.GenerateHandle(_irsSharedMem, out int handle) != KernelResult.Success) + if (context.Process.HandleTable.GenerateHandle(context.Device.System.IirsSharedMem, out int handle) != KernelResult.Success) { throw new InvalidOperationException("Out of handles!"); } diff --git a/Ryujinx.HLE/HOS/Services/ServiceFactory.cs b/Ryujinx.HLE/HOS/Services/ServiceFactory.cs index 3bde7b8779..a26d0fe6c3 100644 --- a/Ryujinx.HLE/HOS/Services/ServiceFactory.cs +++ b/Ryujinx.HLE/HOS/Services/ServiceFactory.cs @@ -43,8 +43,6 @@ namespace Ryujinx.HLE.HOS.Services switch (name) { case "acc:u0": - return new IAccountService(); - case "acc:u1": return new IAccountService(); @@ -52,8 +50,6 @@ namespace Ryujinx.HLE.HOS.Services return new IAddOnContentManager(); case "apm": - return new IManager(); - case "apm:p": return new IManager(); @@ -70,14 +66,8 @@ namespace Ryujinx.HLE.HOS.Services return new IAudioRendererManager(); case "bcat:a": - return new Bcat.IServiceCreator(); - case "bcat:m": - return new Bcat.IServiceCreator(); - case "bcat:u": - return new Bcat.IServiceCreator(); - case "bcat:s": return new Bcat.IServiceCreator(); @@ -100,8 +90,6 @@ namespace Ryujinx.HLE.HOS.Services return new IeTicketService(); case "friend:a": - return new Friend.IServiceCreator(); - case "friend:u": return new Friend.IServiceCreator(); @@ -112,7 +100,7 @@ namespace Ryujinx.HLE.HOS.Services return new IHidServer(system); case "irs": - return new IIrSensorServer(system.IirsSharedMem); + return new IIrSensorServer(); case "ldr:ro": return new IRoInterface(); @@ -149,20 +137,12 @@ namespace Ryujinx.HLE.HOS.Services return new IVulnerabilityManagerInterface(); case "nvdrv": - return new INvDrvServices(system); - case "nvdrv:a": return new INvDrvServices(system); case "pctl:s": - return new IParentalControlServiceFactory(); - case "pctl:r": - return new IParentalControlServiceFactory(); - case "pctl:a": - return new IParentalControlServiceFactory(); - case "pctl": return new IParentalControlServiceFactory(); @@ -173,8 +153,6 @@ namespace Ryujinx.HLE.HOS.Services return new IShellInterface(); case "prepo:a": - return new IPrepoService(); - case "prepo:u": return new IPrepoService(); @@ -197,13 +175,9 @@ namespace Ryujinx.HLE.HOS.Services return new ISslService(); case "time:a": - return new Time.IStaticService(); - case "time:s": - return new Time.IStaticService(); - case "time:u": - return new Time.IStaticService(); + return new Time.IStaticService(system.TimeSharedMem); case "vi:m": return new IManagerRootService(); diff --git a/Ryujinx.HLE/HOS/Services/Time/IStaticService.cs b/Ryujinx.HLE/HOS/Services/Time/IStaticService.cs index fcbaa49216..398c99583d 100644 --- a/Ryujinx.HLE/HOS/Services/Time/IStaticService.cs +++ b/Ryujinx.HLE/HOS/Services/Time/IStaticService.cs @@ -1,4 +1,7 @@ using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel.Common; +using Ryujinx.HLE.HOS.Kernel.Memory; +using Ryujinx.HLE.HOS.Kernel.Process; using System; using System.Collections.Generic; @@ -12,7 +15,9 @@ namespace Ryujinx.HLE.HOS.Services.Time private static readonly DateTime StartupDate = DateTime.UtcNow; - public IStaticService() + private KSharedMemory _timeSharedMem; + + public IStaticService(KSharedMemory timeSharedMem) { _commands = new Dictionary { @@ -21,8 +26,11 @@ namespace Ryujinx.HLE.HOS.Services.Time { 2, GetStandardSteadyClock }, { 3, GetTimeZoneService }, { 4, GetStandardLocalSystemClock }, + { 20, GetSharedMemoryNativeHandle }, { 300, CalculateMonotonicSystemClockBaseTimePoint } }; + + _timeSharedMem = timeSharedMem; } public long GetStandardUserSystemClock(ServiceCtx context) @@ -60,6 +68,20 @@ namespace Ryujinx.HLE.HOS.Services.Time return 0; } + public long GetSharedMemoryNativeHandle(ServiceCtx context) + { + KHandleTable handleTable = context.Process.HandleTable; + + if (handleTable.GenerateHandle(_timeSharedMem, out int handle) != KernelResult.Success) + { + throw new InvalidOperationException("Out of handles!"); + } + + context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle); + + return 0; + } + public long CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx context) { long timeOffset = (long)(DateTime.UtcNow - StartupDate).TotalSeconds;