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 /Ryujinx.HLE/HOS/Services/Time | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Time')
39 files changed, 0 insertions, 5136 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockContextWriter.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockContextWriter.cs deleted file mode 100644 index 14d3cb24..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockContextWriter.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - class EphemeralNetworkSystemClockContextWriter : SystemClockContextUpdateCallback - { - protected override ResultCode Update() - { - return ResultCode.Success; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs deleted file mode 100644 index 003863e4..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - class EphemeralNetworkSystemClockCore : SystemClockCore - { - public EphemeralNetworkSystemClockCore(SteadyClockCore steadyClockCore) : base(steadyClockCore) { } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/LocalSystemClockContextWriter.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/LocalSystemClockContextWriter.cs deleted file mode 100644 index fb7ebdc5..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/LocalSystemClockContextWriter.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - class LocalSystemClockContextWriter : SystemClockContextUpdateCallback - { - private TimeSharedMemory _sharedMemory; - - public LocalSystemClockContextWriter(TimeSharedMemory sharedMemory) - { - _sharedMemory = sharedMemory; - } - - protected override ResultCode Update() - { - _sharedMemory.UpdateLocalSystemClockContext(_context); - - return ResultCode.Success; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/NetworkSystemClockContextWriter.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/NetworkSystemClockContextWriter.cs deleted file mode 100644 index 36468ec1..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/NetworkSystemClockContextWriter.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - class NetworkSystemClockContextWriter : SystemClockContextUpdateCallback - { - private TimeSharedMemory _sharedMemory; - - public NetworkSystemClockContextWriter(TimeSharedMemory sharedMemory) - { - _sharedMemory = sharedMemory; - } - - protected override ResultCode Update() - { - _sharedMemory.UpdateNetworkSystemClockContext(_context); - - return ResultCode.Success; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs deleted file mode 100644 index 20c334e8..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - class StandardLocalSystemClockCore : SystemClockCore - { - public StandardLocalSystemClockCore(StandardSteadyClockCore steadyClockCore) : base(steadyClockCore) {} - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs deleted file mode 100644 index aec03485..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Ryujinx.Cpu; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - class StandardNetworkSystemClockCore : SystemClockCore - { - private TimeSpanType _standardNetworkClockSufficientAccuracy; - - public StandardNetworkSystemClockCore(StandardSteadyClockCore steadyClockCore) : base(steadyClockCore) - { - _standardNetworkClockSufficientAccuracy = new TimeSpanType(0); - } - - public bool IsStandardNetworkSystemClockAccuracySufficient(ITickSource tickSource) - { - SteadyClockCore steadyClockCore = GetSteadyClockCore(); - SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(tickSource); - - bool isStandardNetworkClockSufficientAccuracy = false; - - ResultCode result = GetClockContext(tickSource, out SystemClockContext context); - - if (result == ResultCode.Success && context.SteadyTimePoint.GetSpanBetween(currentTimePoint, out long outSpan) == ResultCode.Success) - { - isStandardNetworkClockSufficientAccuracy = outSpan * 1000000000 < _standardNetworkClockSufficientAccuracy.NanoSeconds; - } - - return isStandardNetworkClockSufficientAccuracy; - } - - public void SetStandardNetworkClockSufficientAccuracy(TimeSpanType standardNetworkClockSufficientAccuracy) - { - _standardNetworkClockSufficientAccuracy = standardNetworkClockSufficientAccuracy; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs deleted file mode 100644 index 8392c4b5..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Ryujinx.Cpu; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - class StandardSteadyClockCore : SteadyClockCore - { - private TimeSpanType _setupValue; - private TimeSpanType _testOffset; - private TimeSpanType _internalOffset; - private TimeSpanType _cachedRawTimePoint; - - public StandardSteadyClockCore() - { - _setupValue = TimeSpanType.Zero; - _testOffset = TimeSpanType.Zero; - _internalOffset = TimeSpanType.Zero; - _cachedRawTimePoint = TimeSpanType.Zero; - } - - public override SteadyClockTimePoint GetTimePoint(ITickSource tickSource) - { - SteadyClockTimePoint result = new SteadyClockTimePoint - { - TimePoint = GetCurrentRawTimePoint(tickSource).ToSeconds(), - ClockSourceId = GetClockSourceId() - }; - - return result; - } - - public override TimeSpanType GetTestOffset() - { - return _testOffset; - } - - public override void SetTestOffset(TimeSpanType testOffset) - { - _testOffset = testOffset; - } - - public override TimeSpanType GetInternalOffset() - { - return _internalOffset; - } - - public override void SetInternalOffset(TimeSpanType internalOffset) - { - _internalOffset = internalOffset; - } - - public override TimeSpanType GetCurrentRawTimePoint(ITickSource tickSource) - { - TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency); - - TimeSpanType rawTimePoint = new TimeSpanType(_setupValue.NanoSeconds + ticksTimeSpan.NanoSeconds); - - if (rawTimePoint.NanoSeconds < _cachedRawTimePoint.NanoSeconds) - { - rawTimePoint.NanoSeconds = _cachedRawTimePoint.NanoSeconds; - } - - _cachedRawTimePoint = rawTimePoint; - - return rawTimePoint; - } - - public void SetSetupValue(TimeSpanType setupValue) - { - _setupValue = setupValue; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs deleted file mode 100644 index fa485437..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs +++ /dev/null @@ -1,108 +0,0 @@ -using Ryujinx.Cpu; -using Ryujinx.HLE.HOS.Kernel.Threading; -using System; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - class StandardUserSystemClockCore : SystemClockCore - { - private StandardLocalSystemClockCore _localSystemClockCore; - private StandardNetworkSystemClockCore _networkSystemClockCore; - private bool _autoCorrectionEnabled; - private SteadyClockTimePoint _autoCorrectionTime; - private KEvent _autoCorrectionEvent; - - public StandardUserSystemClockCore(StandardLocalSystemClockCore localSystemClockCore, StandardNetworkSystemClockCore networkSystemClockCore) : base(localSystemClockCore.GetSteadyClockCore()) - { - _localSystemClockCore = localSystemClockCore; - _networkSystemClockCore = networkSystemClockCore; - _autoCorrectionEnabled = false; - _autoCorrectionTime = SteadyClockTimePoint.GetRandom(); - _autoCorrectionEvent = null; - } - - protected override ResultCode Flush(SystemClockContext context) - { - // As UserSystemClock isn't a real system clock, this shouldn't happens. - throw new NotImplementedException(); - } - - public override ResultCode GetClockContext(ITickSource tickSource, out SystemClockContext context) - { - ResultCode result = ApplyAutomaticCorrection(tickSource, false); - - context = new SystemClockContext(); - - if (result == ResultCode.Success) - { - return _localSystemClockCore.GetClockContext(tickSource, out context); - } - - return result; - } - - public override ResultCode SetClockContext(SystemClockContext context) - { - return ResultCode.NotImplemented; - } - - private ResultCode ApplyAutomaticCorrection(ITickSource tickSource, bool autoCorrectionEnabled) - { - ResultCode result = ResultCode.Success; - - if (_autoCorrectionEnabled != autoCorrectionEnabled && _networkSystemClockCore.IsClockSetup(tickSource)) - { - result = _networkSystemClockCore.GetClockContext(tickSource, out SystemClockContext context); - - if (result == ResultCode.Success) - { - _localSystemClockCore.SetClockContext(context); - } - } - - return result; - } - - internal void CreateAutomaticCorrectionEvent(Horizon system) - { - _autoCorrectionEvent = new KEvent(system.KernelContext); - } - - public ResultCode SetAutomaticCorrectionEnabled(ITickSource tickSource, bool autoCorrectionEnabled) - { - ResultCode result = ApplyAutomaticCorrection(tickSource, autoCorrectionEnabled); - - if (result == ResultCode.Success) - { - _autoCorrectionEnabled = autoCorrectionEnabled; - } - - return result; - } - - public bool IsAutomaticCorrectionEnabled() - { - return _autoCorrectionEnabled; - } - - public KReadableEvent GetAutomaticCorrectionReadableEvent() - { - return _autoCorrectionEvent.ReadableEvent; - } - - public void SetAutomaticCorrectionUpdatedTime(SteadyClockTimePoint steadyClockTimePoint) - { - _autoCorrectionTime = steadyClockTimePoint; - } - - public SteadyClockTimePoint GetAutomaticCorrectionUpdatedTime() - { - return _autoCorrectionTime; - } - - public void SignalAutomaticCorrectionEvent() - { - _autoCorrectionEvent.WritableEvent.Signal(); - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs deleted file mode 100644 index 18da4ed3..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs +++ /dev/null @@ -1,98 +0,0 @@ -using Ryujinx.Common.Utilities; -using Ryujinx.Cpu; -using System; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - abstract class SteadyClockCore - { - private UInt128 _clockSourceId; - private bool _isRtcResetDetected; - private bool _isInitialized; - - public SteadyClockCore() - { - _clockSourceId = UInt128Utils.CreateRandom(); - _isRtcResetDetected = false; - _isInitialized = false; - } - - public UInt128 GetClockSourceId() - { - return _clockSourceId; - } - - public void SetClockSourceId(UInt128 clockSourceId) - { - _clockSourceId = clockSourceId; - } - - public void SetRtcReset() - { - _isRtcResetDetected = true; - } - - public virtual TimeSpanType GetTestOffset() - { - return new TimeSpanType(0); - } - - public virtual void SetTestOffset(TimeSpanType testOffset) {} - - public ResultCode GetRtcValue(out ulong rtcValue) - { - rtcValue = 0; - - return ResultCode.NotImplemented; - } - - public bool IsRtcResetDetected() - { - return _isRtcResetDetected; - } - - public ResultCode GetSetupResultValue() - { - return ResultCode.Success; - } - - public virtual TimeSpanType GetInternalOffset() - { - return new TimeSpanType(0); - } - - public virtual void SetInternalOffset(TimeSpanType internalOffset) {} - - public virtual SteadyClockTimePoint GetTimePoint(ITickSource tickSource) - { - throw new NotImplementedException(); - } - - public virtual TimeSpanType GetCurrentRawTimePoint(ITickSource tickSource) - { - SteadyClockTimePoint timePoint = GetTimePoint(tickSource); - - return TimeSpanType.FromSeconds(timePoint.TimePoint); - } - - public SteadyClockTimePoint GetCurrentTimePoint(ITickSource tickSource) - { - SteadyClockTimePoint result = GetTimePoint(tickSource); - - result.TimePoint += GetTestOffset().ToSeconds(); - result.TimePoint += GetInternalOffset().ToSeconds(); - - return result; - } - - public bool IsInitialized() - { - return _isInitialized; - } - - public void MarkInitialized() - { - _isInitialized = true; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockContextUpdateCallback.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockContextUpdateCallback.cs deleted file mode 100644 index 6229f5ed..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockContextUpdateCallback.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Ryujinx.HLE.HOS.Kernel.Threading; -using System.Collections.Generic; -using System.Threading; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - abstract class SystemClockContextUpdateCallback - { - private List<KWritableEvent> _operationEventList; - protected SystemClockContext _context; - private bool _hasContext; - - public SystemClockContextUpdateCallback() - { - _operationEventList = new List<KWritableEvent>(); - _context = new SystemClockContext(); - _hasContext = false; - } - - private bool NeedUpdate(SystemClockContext context) - { - if (_hasContext) - { - return _context.Offset != context.Offset || _context.SteadyTimePoint.ClockSourceId != context.SteadyTimePoint.ClockSourceId; - } - - return true; - } - - public void RegisterOperationEvent(KWritableEvent writableEvent) - { - Monitor.Enter(_operationEventList); - _operationEventList.Add(writableEvent); - Monitor.Exit(_operationEventList); - } - - private void BroadcastOperationEvent() - { - Monitor.Enter(_operationEventList); - - foreach (KWritableEvent e in _operationEventList) - { - e.Signal(); - } - - Monitor.Exit(_operationEventList); - } - - protected abstract ResultCode Update(); - - public ResultCode Update(SystemClockContext context) - { - ResultCode result = ResultCode.Success; - - if (NeedUpdate(context)) - { - _context = context; - _hasContext = true; - - result = Update(); - - if (result == ResultCode.Success) - { - BroadcastOperationEvent(); - } - } - - return result; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs deleted file mode 100644 index f4bbaa60..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs +++ /dev/null @@ -1,144 +0,0 @@ -using Ryujinx.Cpu; -using Ryujinx.HLE.HOS.Kernel.Threading; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - abstract class SystemClockCore - { - private SteadyClockCore _steadyClockCore; - private SystemClockContext _context; - private bool _isInitialized; - private SystemClockContextUpdateCallback _systemClockContextUpdateCallback; - - public SystemClockCore(SteadyClockCore steadyClockCore) - { - _steadyClockCore = steadyClockCore; - _context = new SystemClockContext(); - _isInitialized = false; - - _context.SteadyTimePoint.ClockSourceId = steadyClockCore.GetClockSourceId(); - _systemClockContextUpdateCallback = null; - } - - public virtual SteadyClockCore GetSteadyClockCore() - { - return _steadyClockCore; - } - - public ResultCode GetCurrentTime(ITickSource tickSource, out long posixTime) - { - posixTime = 0; - - SteadyClockTimePoint currentTimePoint = _steadyClockCore.GetCurrentTimePoint(tickSource); - - ResultCode result = GetClockContext(tickSource, out SystemClockContext clockContext); - - if (result == ResultCode.Success) - { - result = ResultCode.TimeMismatch; - - if (currentTimePoint.ClockSourceId == clockContext.SteadyTimePoint.ClockSourceId) - { - posixTime = clockContext.Offset + currentTimePoint.TimePoint; - - result = 0; - } - } - - return result; - } - - public ResultCode SetCurrentTime(ITickSource tickSource, long posixTime) - { - SteadyClockTimePoint currentTimePoint = _steadyClockCore.GetCurrentTimePoint(tickSource); - - SystemClockContext clockContext = new SystemClockContext() - { - Offset = posixTime - currentTimePoint.TimePoint, - SteadyTimePoint = currentTimePoint - }; - - ResultCode result = SetClockContext(clockContext); - - if (result == ResultCode.Success) - { - result = Flush(clockContext); - } - - return result; - } - - public virtual ResultCode GetClockContext(ITickSource tickSource, out SystemClockContext context) - { - context = _context; - - return ResultCode.Success; - } - - public virtual ResultCode SetClockContext(SystemClockContext context) - { - _context = context; - - return ResultCode.Success; - } - - protected virtual ResultCode Flush(SystemClockContext context) - { - if (_systemClockContextUpdateCallback == null) - { - return ResultCode.Success; - } - - return _systemClockContextUpdateCallback.Update(context); - } - - public void SetUpdateCallbackInstance(SystemClockContextUpdateCallback systemClockContextUpdateCallback) - { - _systemClockContextUpdateCallback = systemClockContextUpdateCallback; - } - - public void RegisterOperationEvent(KWritableEvent writableEvent) - { - if (_systemClockContextUpdateCallback != null) - { - _systemClockContextUpdateCallback.RegisterOperationEvent(writableEvent); - } - } - - public ResultCode SetSystemClockContext(SystemClockContext context) - { - ResultCode result = SetClockContext(context); - - if (result == ResultCode.Success) - { - result = Flush(context); - } - - return result; - } - - public bool IsInitialized() - { - return _isInitialized; - } - - public void MarkInitialized() - { - _isInitialized = true; - } - - public bool IsClockSetup(ITickSource tickSource) - { - ResultCode result = GetClockContext(tickSource, out SystemClockContext context); - - if (result == ResultCode.Success) - { - SteadyClockTimePoint steadyClockTimePoint = _steadyClockCore.GetCurrentTimePoint(tickSource); - - return steadyClockTimePoint.ClockSourceId == context.SteadyTimePoint.ClockSourceId; - } - - return false; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs deleted file mode 100644 index fe74da7e..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Ryujinx.Cpu; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - class TickBasedSteadyClockCore : SteadyClockCore - { - public TickBasedSteadyClockCore() {} - - public override SteadyClockTimePoint GetTimePoint(ITickSource tickSource) - { - SteadyClockTimePoint result = new SteadyClockTimePoint - { - TimePoint = 0, - ClockSourceId = GetClockSourceId() - }; - - TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency); - - result.TimePoint = ticksTimeSpan.ToSeconds(); - - return result; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs deleted file mode 100644 index 07c1b405..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/ClockSnapshot.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Ryujinx.HLE.HOS.Services.Time.TimeZone; -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - [StructLayout(LayoutKind.Sequential, Size = 0xD0)] - struct ClockSnapshot - { - public SystemClockContext UserContext; - public SystemClockContext NetworkContext; - public long UserTime; - public long NetworkTime; - public CalendarTime UserCalendarTime; - public CalendarTime NetworkCalendarTime; - public CalendarAdditionalInfo UserCalendarAdditionalTime; - public CalendarAdditionalInfo NetworkCalendarAdditionalTime; - public SteadyClockTimePoint SteadyClockTimePoint; - - private LocationNameStorageHolder _locationName; - - public Span<byte> LocationName => MemoryMarshal.Cast<LocationNameStorageHolder, byte>(MemoryMarshal.CreateSpan(ref _locationName, LocationNameStorageHolder.Size)); - - [MarshalAs(UnmanagedType.I1)] - public bool IsAutomaticCorrectionEnabled; - public byte Type; - public ushort Unknown; - - - [StructLayout(LayoutKind.Sequential, Pack = 1, Size = Size)] - private struct LocationNameStorageHolder - { - public const int Size = 0x24; - } - - public static ResultCode GetCurrentTime(out long currentTime, SteadyClockTimePoint steadyClockTimePoint, SystemClockContext context) - { - currentTime = 0; - - if (steadyClockTimePoint.ClockSourceId == context.SteadyTimePoint.ClockSourceId) - { - currentTime = steadyClockTimePoint.TimePoint + context.Offset; - - return ResultCode.Success; - } - - return ResultCode.TimeMismatch; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SteadyClockTimePoint.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SteadyClockTimePoint.cs deleted file mode 100644 index 729e11b6..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SteadyClockTimePoint.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Ryujinx.Common.Utilities; -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct SteadyClockTimePoint - { - public long TimePoint; - public UInt128 ClockSourceId; - - public ResultCode GetSpanBetween(SteadyClockTimePoint other, out long outSpan) - { - outSpan = 0; - - if (ClockSourceId == other.ClockSourceId) - { - try - { - outSpan = checked(other.TimePoint - TimePoint); - - return ResultCode.Success; - } - catch (OverflowException) - { - return ResultCode.Overflow; - } - } - - return ResultCode.Overflow; - } - - public static SteadyClockTimePoint GetRandom() - { - return new SteadyClockTimePoint - { - TimePoint = 0, - ClockSourceId = UInt128Utils.CreateRandom() - }; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SystemClockContext.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SystemClockContext.cs deleted file mode 100644 index 6b589c28..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/SystemClockContext.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct SystemClockContext - { - public long Offset; - public SteadyClockTimePoint SteadyTimePoint; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/TimeSpanType.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/Types/TimeSpanType.cs deleted file mode 100644 index 0070193f..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/Types/TimeSpanType.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.Clock -{ - [StructLayout(LayoutKind.Sequential)] - struct TimeSpanType - { - private const long NanoSecondsPerSecond = 1000000000; - - public static readonly TimeSpanType Zero = new TimeSpanType(0); - - public long NanoSeconds; - - public TimeSpanType(long nanoSeconds) - { - NanoSeconds = nanoSeconds; - } - - public long ToSeconds() - { - return NanoSeconds / NanoSecondsPerSecond; - } - - public TimeSpanType AddSeconds(long seconds) - { - return new TimeSpanType(NanoSeconds + (seconds * NanoSecondsPerSecond)); - } - - public bool IsDaylightSavingTime() - { - return DateTime.UnixEpoch.AddSeconds(ToSeconds()).ToLocalTime().IsDaylightSavingTime(); - } - - public static TimeSpanType FromSeconds(long seconds) - { - return new TimeSpanType(seconds * NanoSecondsPerSecond); - } - - public static TimeSpanType FromTimeSpan(TimeSpan timeSpan) - { - return new TimeSpanType((long)(timeSpan.TotalMilliseconds * 1000000)); - } - - public static TimeSpanType FromTicks(ulong ticks, ulong frequency) - { - return FromSeconds((long)ticks / (long)frequency); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/IAlarmService.cs b/Ryujinx.HLE/HOS/Services/Time/IAlarmService.cs deleted file mode 100644 index 092fa8ce..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/IAlarmService.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Time -{ - [Service("time:al")] // 9.0.0+ - class IAlarmService : IpcService - { - public IAlarmService(ServiceCtx context) { } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/IPowerStateRequestHandler.cs b/Ryujinx.HLE/HOS/Services/Time/IPowerStateRequestHandler.cs deleted file mode 100644 index 8ec55c15..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/IPowerStateRequestHandler.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Time -{ - [Service("time:p")] // 9.0.0+ - class IPowerStateRequestHandler : IpcService - { - public IPowerStateRequestHandler(ServiceCtx context) { } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs b/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs deleted file mode 100644 index 31548b80..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForGlue.cs +++ /dev/null @@ -1,184 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.HLE.HOS.Services.Pcv.Bpc; -using Ryujinx.HLE.HOS.Services.Settings; -using Ryujinx.HLE.HOS.Services.Time.Clock; -using Ryujinx.HLE.HOS.Services.Time.StaticService; -using System; - -namespace Ryujinx.HLE.HOS.Services.Time -{ - [Service("time:a", TimePermissions.Admin)] - [Service("time:r", TimePermissions.Repair)] - [Service("time:u", TimePermissions.User)] - class IStaticServiceForGlue : IpcService - { - private IStaticServiceForPsc _inner; - private TimePermissions _permissions; - - public IStaticServiceForGlue(ServiceCtx context, TimePermissions permissions) : base(context.Device.System.TimeServer) - { - _permissions = permissions; - _inner = new IStaticServiceForPsc(context, permissions); - _inner.TrySetServer(Server); - _inner.SetParent(this); - } - - [CommandCmif(0)] - // GetStandardUserSystemClock() -> object<nn::timesrv::detail::service::ISystemClock> - public ResultCode GetStandardUserSystemClock(ServiceCtx context) - { - return _inner.GetStandardUserSystemClock(context); - } - - [CommandCmif(1)] - // GetStandardNetworkSystemClock() -> object<nn::timesrv::detail::service::ISystemClock> - public ResultCode GetStandardNetworkSystemClock(ServiceCtx context) - { - return _inner.GetStandardNetworkSystemClock(context); - } - - [CommandCmif(2)] - // GetStandardSteadyClock() -> object<nn::timesrv::detail::service::ISteadyClock> - public ResultCode GetStandardSteadyClock(ServiceCtx context) - { - return _inner.GetStandardSteadyClock(context); - } - - [CommandCmif(3)] - // GetTimeZoneService() -> object<nn::timesrv::detail::service::ITimeZoneService> - public ResultCode GetTimeZoneService(ServiceCtx context) - { - MakeObject(context, new ITimeZoneServiceForGlue(TimeManager.Instance.TimeZone, (_permissions & TimePermissions.TimeZoneWritableMask) != 0)); - - return ResultCode.Success; - } - - [CommandCmif(4)] - // GetStandardLocalSystemClock() -> object<nn::timesrv::detail::service::ISystemClock> - public ResultCode GetStandardLocalSystemClock(ServiceCtx context) - { - return _inner.GetStandardLocalSystemClock(context); - } - - [CommandCmif(5)] // 4.0.0+ - // GetEphemeralNetworkSystemClock() -> object<nn::timesrv::detail::service::ISystemClock> - public ResultCode GetEphemeralNetworkSystemClock(ServiceCtx context) - { - return _inner.GetEphemeralNetworkSystemClock(context); - } - - [CommandCmif(20)] // 6.0.0+ - // GetSharedMemoryNativeHandle() -> handle<copy> - public ResultCode GetSharedMemoryNativeHandle(ServiceCtx context) - { - return _inner.GetSharedMemoryNativeHandle(context); - } - - [CommandCmif(50)] // 4.0.0+ - // SetStandardSteadyClockInternalOffset(nn::TimeSpanType internal_offset) - public ResultCode SetStandardSteadyClockInternalOffset(ServiceCtx context) - { - if ((_permissions & TimePermissions.SteadyClockWritableMask) == 0) - { - return ResultCode.PermissionDenied; - } - - TimeSpanType internalOffset = context.RequestData.ReadStruct<TimeSpanType>(); - - // TODO: set:sys SetExternalSteadyClockInternalOffset(internalOffset.ToSeconds()) - - return ResultCode.Success; - } - - [CommandCmif(51)] // 9.0.0+ - // GetStandardSteadyClockRtcValue() -> u64 - public ResultCode GetStandardSteadyClockRtcValue(ServiceCtx context) - { - ResultCode result = (ResultCode)IRtcManager.GetExternalRtcValue(out ulong rtcValue); - - if (result == ResultCode.Success) - { - context.ResponseData.Write(rtcValue); - } - - return result; - } - - [CommandCmif(100)] - // IsStandardUserSystemClockAutomaticCorrectionEnabled() -> bool - public ResultCode IsStandardUserSystemClockAutomaticCorrectionEnabled(ServiceCtx context) - { - return _inner.IsStandardUserSystemClockAutomaticCorrectionEnabled(context); - } - - [CommandCmif(101)] - // SetStandardUserSystemClockAutomaticCorrectionEnabled(b8) - public ResultCode SetStandardUserSystemClockAutomaticCorrectionEnabled(ServiceCtx context) - { - return _inner.SetStandardUserSystemClockAutomaticCorrectionEnabled(context); - } - - [CommandCmif(102)] // 5.0.0+ - // GetStandardUserSystemClockInitialYear() -> u32 - public ResultCode GetStandardUserSystemClockInitialYear(ServiceCtx context) - { - if (!NxSettings.Settings.TryGetValue("time!standard_user_clock_initial_year", out object standardUserSystemClockInitialYear)) - { - throw new InvalidOperationException("standard_user_clock_initial_year isn't defined in system settings!"); - } - - context.ResponseData.Write((int)standardUserSystemClockInitialYear); - - return ResultCode.Success; - } - - [CommandCmif(200)] // 3.0.0+ - // IsStandardNetworkSystemClockAccuracySufficient() -> bool - public ResultCode IsStandardNetworkSystemClockAccuracySufficient(ServiceCtx context) - { - return _inner.IsStandardNetworkSystemClockAccuracySufficient(context); - } - - [CommandCmif(201)] // 6.0.0+ - // GetStandardUserSystemClockAutomaticCorrectionUpdatedTime() -> nn::time::SteadyClockTimePoint - public ResultCode GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(ServiceCtx context) - { - return _inner.GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(context); - } - - [CommandCmif(300)] // 4.0.0+ - // CalculateMonotonicSystemClockBaseTimePoint(nn::time::SystemClockContext) -> s64 - public ResultCode CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx context) - { - return _inner.CalculateMonotonicSystemClockBaseTimePoint(context); - } - - [CommandCmif(400)] // 4.0.0+ - // GetClockSnapshot(u8) -> buffer<nn::time::sf::ClockSnapshot, 0x1a> - public ResultCode GetClockSnapshot(ServiceCtx context) - { - return _inner.GetClockSnapshot(context); - } - - [CommandCmif(401)] // 4.0.0+ - // GetClockSnapshotFromSystemClockContext(u8, nn::time::SystemClockContext, nn::time::SystemClockContext) -> buffer<nn::time::sf::ClockSnapshot, 0x1a> - public ResultCode GetClockSnapshotFromSystemClockContext(ServiceCtx context) - { - return _inner.GetClockSnapshotFromSystemClockContext(context); - } - - [CommandCmif(500)] // 4.0.0+ - // CalculateStandardUserSystemClockDifferenceByUser(buffer<nn::time::sf::ClockSnapshot, 0x19>, buffer<nn::time::sf::ClockSnapshot, 0x19>) -> nn::TimeSpanType - public ResultCode CalculateStandardUserSystemClockDifferenceByUser(ServiceCtx context) - { - return _inner.CalculateStandardUserSystemClockDifferenceByUser(context); - } - - [CommandCmif(501)] // 4.0.0+ - // CalculateSpanBetween(buffer<nn::time::sf::ClockSnapshot, 0x19>, buffer<nn::time::sf::ClockSnapshot, 0x19>) -> nn::TimeSpanType - public ResultCode CalculateSpanBetween(ServiceCtx context) - { - return _inner.CalculateSpanBetween(context); - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs b/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs deleted file mode 100644 index 145d4e3b..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/IStaticServiceForPsc.cs +++ /dev/null @@ -1,433 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Cpu; -using Ryujinx.HLE.HOS.Ipc; -using Ryujinx.HLE.HOS.Services.Time.Clock; -using Ryujinx.HLE.HOS.Services.Time.StaticService; -using Ryujinx.HLE.HOS.Services.Time.TimeZone; -using Ryujinx.Horizon.Common; -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace Ryujinx.HLE.HOS.Services.Time -{ - [Service("time:s", TimePermissions.System)] - [Service("time:su", TimePermissions.SystemUpdate)] - class IStaticServiceForPsc : IpcService - { - private TimeManager _timeManager; - private TimePermissions _permissions; - - private int _timeSharedMemoryNativeHandle = 0; - - public IStaticServiceForPsc(ServiceCtx context, TimePermissions permissions) : this(TimeManager.Instance, permissions) {} - - public IStaticServiceForPsc(TimeManager manager, TimePermissions permissions) - { - _permissions = permissions; - _timeManager = manager; - } - - [CommandCmif(0)] - // GetStandardUserSystemClock() -> object<nn::timesrv::detail::service::ISystemClock> - public ResultCode GetStandardUserSystemClock(ServiceCtx context) - { - MakeObject(context, new ISystemClock(_timeManager.StandardUserSystemClock, - (_permissions & TimePermissions.UserSystemClockWritableMask) != 0, - (_permissions & TimePermissions.BypassUninitialized) != 0)); - - return ResultCode.Success; - } - - [CommandCmif(1)] - // GetStandardNetworkSystemClock() -> object<nn::timesrv::detail::service::ISystemClock> - public ResultCode GetStandardNetworkSystemClock(ServiceCtx context) - { - MakeObject(context, new ISystemClock(_timeManager.StandardNetworkSystemClock, - (_permissions & TimePermissions.NetworkSystemClockWritableMask) != 0, - (_permissions & TimePermissions.BypassUninitialized) != 0)); - - return ResultCode.Success; - } - - [CommandCmif(2)] - // GetStandardSteadyClock() -> object<nn::timesrv::detail::service::ISteadyClock> - public ResultCode GetStandardSteadyClock(ServiceCtx context) - { - MakeObject(context, new ISteadyClock(_timeManager.StandardSteadyClock, - (_permissions & TimePermissions.SteadyClockWritableMask) != 0, - (_permissions & TimePermissions.BypassUninitialized) != 0)); - - return ResultCode.Success; - } - - [CommandCmif(3)] - // GetTimeZoneService() -> object<nn::timesrv::detail::service::ITimeZoneService> - public ResultCode GetTimeZoneService(ServiceCtx context) - { - MakeObject(context, new ITimeZoneServiceForPsc(_timeManager.TimeZone.Manager, - (_permissions & TimePermissions.TimeZoneWritableMask) != 0)); - - return ResultCode.Success; - } - - [CommandCmif(4)] - // GetStandardLocalSystemClock() -> object<nn::timesrv::detail::service::ISystemClock> - public ResultCode GetStandardLocalSystemClock(ServiceCtx context) - { - MakeObject(context, new ISystemClock(_timeManager.StandardLocalSystemClock, - (_permissions & TimePermissions.LocalSystemClockWritableMask) != 0, - (_permissions & TimePermissions.BypassUninitialized) != 0)); - - return ResultCode.Success; - } - - [CommandCmif(5)] // 4.0.0+ - // GetEphemeralNetworkSystemClock() -> object<nn::timesrv::detail::service::ISystemClock> - public ResultCode GetEphemeralNetworkSystemClock(ServiceCtx context) - { - MakeObject(context, new ISystemClock(_timeManager.StandardNetworkSystemClock, - (_permissions & TimePermissions.NetworkSystemClockWritableMask) != 0, - (_permissions & TimePermissions.BypassUninitialized) != 0)); - - return ResultCode.Success; - } - - [CommandCmif(20)] // 6.0.0+ - // GetSharedMemoryNativeHandle() -> handle<copy> - public ResultCode GetSharedMemoryNativeHandle(ServiceCtx context) - { - if (_timeSharedMemoryNativeHandle == 0) - { - if (context.Process.HandleTable.GenerateHandle(_timeManager.SharedMemory.GetSharedMemory(), out _timeSharedMemoryNativeHandle) != Result.Success) - { - throw new InvalidOperationException("Out of handles!"); - } - } - - context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_timeSharedMemoryNativeHandle); - - return ResultCode.Success; - } - - [CommandCmif(50)] // 4.0.0+ - // SetStandardSteadyClockInternalOffset(nn::TimeSpanType internal_offset) - public ResultCode SetStandardSteadyClockInternalOffset(ServiceCtx context) - { - // This is only implemented in glue's StaticService. - return ResultCode.NotImplemented; - } - - [CommandCmif(51)] // 9.0.0+ - // GetStandardSteadyClockRtcValue() -> u64 - public ResultCode GetStandardSteadyClockRtcValue(ServiceCtx context) - { - // This is only implemented in glue's StaticService. - return ResultCode.NotImplemented; - } - - [CommandCmif(100)] - // IsStandardUserSystemClockAutomaticCorrectionEnabled() -> bool - public ResultCode IsStandardUserSystemClockAutomaticCorrectionEnabled(ServiceCtx context) - { - StandardUserSystemClockCore userClock = _timeManager.StandardUserSystemClock; - - if (!userClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - context.ResponseData.Write(userClock.IsAutomaticCorrectionEnabled()); - - return ResultCode.Success; - } - - [CommandCmif(101)] - // SetStandardUserSystemClockAutomaticCorrectionEnabled(b8) - public ResultCode SetStandardUserSystemClockAutomaticCorrectionEnabled(ServiceCtx context) - { - SteadyClockCore steadyClock = _timeManager.StandardSteadyClock; - StandardUserSystemClockCore userClock = _timeManager.StandardUserSystemClock; - - if (!userClock.IsInitialized() || !steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - if ((_permissions & TimePermissions.UserSystemClockWritableMask) == 0) - { - return ResultCode.PermissionDenied; - } - - bool autoCorrectionEnabled = context.RequestData.ReadBoolean(); - - ITickSource tickSource = context.Device.System.TickSource; - - ResultCode result = userClock.SetAutomaticCorrectionEnabled(tickSource, autoCorrectionEnabled); - - if (result == ResultCode.Success) - { - _timeManager.SharedMemory.SetAutomaticCorrectionEnabled(autoCorrectionEnabled); - - SteadyClockTimePoint currentTimePoint = userClock.GetSteadyClockCore().GetCurrentTimePoint(tickSource); - - userClock.SetAutomaticCorrectionUpdatedTime(currentTimePoint); - userClock.SignalAutomaticCorrectionEvent(); - } - - return result; - } - - [CommandCmif(102)] // 5.0.0+ - // GetStandardUserSystemClockInitialYear() -> u32 - public ResultCode GetStandardUserSystemClockInitialYear(ServiceCtx context) - { - // This is only implemented in glue's StaticService. - return ResultCode.NotImplemented; - } - - [CommandCmif(200)] // 3.0.0+ - // IsStandardNetworkSystemClockAccuracySufficient() -> bool - public ResultCode IsStandardNetworkSystemClockAccuracySufficient(ServiceCtx context) - { - ITickSource tickSource = context.Device.System.TickSource; - - context.ResponseData.Write(_timeManager.StandardNetworkSystemClock.IsStandardNetworkSystemClockAccuracySufficient(tickSource)); - - return ResultCode.Success; - } - - [CommandCmif(201)] // 6.0.0+ - // GetStandardUserSystemClockAutomaticCorrectionUpdatedTime() -> nn::time::SteadyClockTimePoint - public ResultCode GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(ServiceCtx context) - { - StandardUserSystemClockCore userClock = _timeManager.StandardUserSystemClock; - - if (!userClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - context.ResponseData.WriteStruct(userClock.GetAutomaticCorrectionUpdatedTime()); - - return ResultCode.Success; - } - - [CommandCmif(300)] // 4.0.0+ - // CalculateMonotonicSystemClockBaseTimePoint(nn::time::SystemClockContext) -> s64 - public ResultCode CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx context) - { - SteadyClockCore steadyClock = _timeManager.StandardSteadyClock; - - if (!steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - ITickSource tickSource = context.Device.System.TickSource; - - SystemClockContext otherContext = context.RequestData.ReadStruct<SystemClockContext>(); - SteadyClockTimePoint currentTimePoint = steadyClock.GetCurrentTimePoint(tickSource); - - ResultCode result = ResultCode.TimeMismatch; - - if (currentTimePoint.ClockSourceId == otherContext.SteadyTimePoint.ClockSourceId) - { - TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency); - long baseTimePoint = otherContext.Offset + currentTimePoint.TimePoint - ticksTimeSpan.ToSeconds(); - - context.ResponseData.Write(baseTimePoint); - - result = ResultCode.Success; - } - - return result; - } - - [CommandCmif(400)] // 4.0.0+ - // GetClockSnapshot(u8) -> buffer<nn::time::sf::ClockSnapshot, 0x1a> - public ResultCode GetClockSnapshot(ServiceCtx context) - { - byte type = context.RequestData.ReadByte(); - - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf<ClockSnapshot>()); - - ITickSource tickSource = context.Device.System.TickSource; - - ResultCode result = _timeManager.StandardUserSystemClock.GetClockContext(tickSource, out SystemClockContext userContext); - - if (result == ResultCode.Success) - { - result = _timeManager.StandardNetworkSystemClock.GetClockContext(tickSource, out SystemClockContext networkContext); - - if (result == ResultCode.Success) - { - result = GetClockSnapshotFromSystemClockContextInternal(tickSource, userContext, networkContext, type, out ClockSnapshot clockSnapshot); - - if (result == ResultCode.Success) - { - WriteClockSnapshotFromBuffer(context, context.Request.RecvListBuff[0], clockSnapshot); - } - } - } - - return result; - } - - [CommandCmif(401)] // 4.0.0+ - // GetClockSnapshotFromSystemClockContext(u8, nn::time::SystemClockContext, nn::time::SystemClockContext) -> buffer<nn::time::sf::ClockSnapshot, 0x1a> - public ResultCode GetClockSnapshotFromSystemClockContext(ServiceCtx context) - { - byte type = context.RequestData.ReadByte(); - - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Unsafe.SizeOf<ClockSnapshot>()); - - context.RequestData.BaseStream.Position += 7; - - SystemClockContext userContext = context.RequestData.ReadStruct<SystemClockContext>(); - SystemClockContext networkContext = context.RequestData.ReadStruct<SystemClockContext>(); - - ITickSource tickSource = context.Device.System.TickSource; - - ResultCode result = GetClockSnapshotFromSystemClockContextInternal(tickSource, userContext, networkContext, type, out ClockSnapshot clockSnapshot); - - if (result == ResultCode.Success) - { - WriteClockSnapshotFromBuffer(context, context.Request.RecvListBuff[0], clockSnapshot); - } - - return result; - } - - [CommandCmif(500)] // 4.0.0+ - // CalculateStandardUserSystemClockDifferenceByUser(buffer<nn::time::sf::ClockSnapshot, 0x19>, buffer<nn::time::sf::ClockSnapshot, 0x19>) -> nn::TimeSpanType - public ResultCode CalculateStandardUserSystemClockDifferenceByUser(ServiceCtx context) - { - ClockSnapshot clockSnapshotA = ReadClockSnapshotFromBuffer(context, context.Request.PtrBuff[0]); - ClockSnapshot clockSnapshotB = ReadClockSnapshotFromBuffer(context, context.Request.PtrBuff[1]); - TimeSpanType difference = TimeSpanType.FromSeconds(clockSnapshotB.UserContext.Offset - clockSnapshotA.UserContext.Offset); - - if (clockSnapshotB.UserContext.SteadyTimePoint.ClockSourceId != clockSnapshotA.UserContext.SteadyTimePoint.ClockSourceId || (clockSnapshotB.IsAutomaticCorrectionEnabled && clockSnapshotA.IsAutomaticCorrectionEnabled)) - { - difference = new TimeSpanType(0); - } - - context.ResponseData.Write(difference.NanoSeconds); - - return ResultCode.Success; - } - - [CommandCmif(501)] // 4.0.0+ - // CalculateSpanBetween(buffer<nn::time::sf::ClockSnapshot, 0x19>, buffer<nn::time::sf::ClockSnapshot, 0x19>) -> nn::TimeSpanType - public ResultCode CalculateSpanBetween(ServiceCtx context) - { - ClockSnapshot clockSnapshotA = ReadClockSnapshotFromBuffer(context, context.Request.PtrBuff[0]); - ClockSnapshot clockSnapshotB = ReadClockSnapshotFromBuffer(context, context.Request.PtrBuff[1]); - - TimeSpanType result; - - ResultCode resultCode = clockSnapshotA.SteadyClockTimePoint.GetSpanBetween(clockSnapshotB.SteadyClockTimePoint, out long timeSpan); - - if (resultCode != ResultCode.Success) - { - resultCode = ResultCode.TimeNotFound; - - if (clockSnapshotA.NetworkTime != 0 && clockSnapshotB.NetworkTime != 0) - { - result = TimeSpanType.FromSeconds(clockSnapshotB.NetworkTime - clockSnapshotA.NetworkTime); - resultCode = ResultCode.Success; - } - else - { - return resultCode; - } - } - else - { - result = TimeSpanType.FromSeconds(timeSpan); - } - - context.ResponseData.Write(result.NanoSeconds); - - return resultCode; - } - - private ResultCode GetClockSnapshotFromSystemClockContextInternal(ITickSource tickSource, SystemClockContext userContext, SystemClockContext networkContext, byte type, out ClockSnapshot clockSnapshot) - { - clockSnapshot = new ClockSnapshot(); - - SteadyClockCore steadyClockCore = _timeManager.StandardSteadyClock; - SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(tickSource); - - clockSnapshot.IsAutomaticCorrectionEnabled = _timeManager.StandardUserSystemClock.IsAutomaticCorrectionEnabled(); - clockSnapshot.UserContext = userContext; - clockSnapshot.NetworkContext = networkContext; - clockSnapshot.SteadyClockTimePoint = currentTimePoint; - - ResultCode result = _timeManager.TimeZone.Manager.GetDeviceLocationName(out string deviceLocationName); - - if (result != ResultCode.Success) - { - return result; - } - - ReadOnlySpan<byte> tzName = Encoding.ASCII.GetBytes(deviceLocationName); - - tzName.CopyTo(clockSnapshot.LocationName); - - result = ClockSnapshot.GetCurrentTime(out clockSnapshot.UserTime, currentTimePoint, clockSnapshot.UserContext); - - if (result == ResultCode.Success) - { - result = _timeManager.TimeZone.Manager.ToCalendarTimeWithMyRules(clockSnapshot.UserTime, out CalendarInfo userCalendarInfo); - - if (result == ResultCode.Success) - { - clockSnapshot.UserCalendarTime = userCalendarInfo.Time; - clockSnapshot.UserCalendarAdditionalTime = userCalendarInfo.AdditionalInfo; - - if (ClockSnapshot.GetCurrentTime(out clockSnapshot.NetworkTime, currentTimePoint, clockSnapshot.NetworkContext) != ResultCode.Success) - { - clockSnapshot.NetworkTime = 0; - } - - result = _timeManager.TimeZone.Manager.ToCalendarTimeWithMyRules(clockSnapshot.NetworkTime, out CalendarInfo networkCalendarInfo); - - if (result == ResultCode.Success) - { - clockSnapshot.NetworkCalendarTime = networkCalendarInfo.Time; - clockSnapshot.NetworkCalendarAdditionalTime = networkCalendarInfo.AdditionalInfo; - clockSnapshot.Type = type; - - // Probably a version field? - clockSnapshot.Unknown = 0; - } - } - } - - return result; - } - - private ClockSnapshot ReadClockSnapshotFromBuffer(ServiceCtx context, IpcPtrBuffDesc ipcDesc) - { - Debug.Assert(ipcDesc.Size == (ulong)Unsafe.SizeOf<ClockSnapshot>()); - - byte[] temp = new byte[ipcDesc.Size]; - - context.Memory.Read(ipcDesc.Position, temp); - - using (BinaryReader bufferReader = new BinaryReader(new MemoryStream(temp))) - { - return bufferReader.ReadStruct<ClockSnapshot>(); - } - } - - private void WriteClockSnapshotFromBuffer(ServiceCtx context, IpcRecvListBuffDesc ipcDesc, ClockSnapshot clockSnapshot) - { - MemoryHelper.Write(context.Memory, ipcDesc.Position, clockSnapshot); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs b/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs deleted file mode 100644 index 6c9c15f1..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs +++ /dev/null @@ -1,231 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Cpu; -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Ipc; -using Ryujinx.HLE.HOS.Services.Time.Clock; -using Ryujinx.HLE.Utilities; -using Ryujinx.Horizon.Common; -using System; -using System.IO; - -namespace Ryujinx.HLE.HOS.Services.Time -{ - [Service("time:m")] // 9.0.0+ - class ITimeServiceManager : IpcService - { - private TimeManager _timeManager; - private int _automaticCorrectionEvent; - - public ITimeServiceManager(ServiceCtx context) - { - _timeManager = TimeManager.Instance; - _automaticCorrectionEvent = 0; - } - - [CommandCmif(0)] - // GetUserStaticService() -> object<nn::timesrv::detail::service::IStaticService> - public ResultCode GetUserStaticService(ServiceCtx context) - { - MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.User)); - - return ResultCode.Success; - } - - [CommandCmif(5)] - // GetAdminStaticService() -> object<nn::timesrv::detail::service::IStaticService> - public ResultCode GetAdminStaticService(ServiceCtx context) - { - MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.Admin)); - - return ResultCode.Success; - } - - [CommandCmif(6)] - // GetRepairStaticService() -> object<nn::timesrv::detail::service::IStaticService> - public ResultCode GetRepairStaticService(ServiceCtx context) - { - MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.Repair)); - - return ResultCode.Success; - } - - [CommandCmif(9)] - // GetManufactureStaticService() -> object<nn::timesrv::detail::service::IStaticService> - public ResultCode GetManufactureStaticService(ServiceCtx context) - { - MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.Manufacture)); - - return ResultCode.Success; - } - - [CommandCmif(10)] - // SetupStandardSteadyClock(nn::util::Uuid clock_source_id, nn::TimeSpanType setup_value, nn::TimeSpanType internal_offset, nn::TimeSpanType test_offset, bool is_rtc_reset_detected) - public ResultCode SetupStandardSteadyClock(ServiceCtx context) - { - UInt128 clockSourceId = context.RequestData.ReadStruct<UInt128>(); - TimeSpanType setupValue = context.RequestData.ReadStruct<TimeSpanType>(); - TimeSpanType internalOffset = context.RequestData.ReadStruct<TimeSpanType>(); - TimeSpanType testOffset = context.RequestData.ReadStruct<TimeSpanType>(); - bool isRtcResetDetected = context.RequestData.ReadBoolean(); - - ITickSource tickSource = context.Device.System.TickSource; - - _timeManager.SetupStandardSteadyClock(tickSource, clockSourceId, setupValue, internalOffset, testOffset, isRtcResetDetected); - - return ResultCode.Success; - } - - [CommandCmif(11)] - // SetupStandardLocalSystemClock(nn::time::SystemClockContext context, nn::time::PosixTime posix_time) - public ResultCode SetupStandardLocalSystemClock(ServiceCtx context) - { - SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>(); - long posixTime = context.RequestData.ReadInt64(); - - ITickSource tickSource = context.Device.System.TickSource; - - _timeManager.SetupStandardLocalSystemClock(tickSource, clockContext, posixTime); - - return ResultCode.Success; - } - - [CommandCmif(12)] - // SetupStandardNetworkSystemClock(nn::time::SystemClockContext context, nn::TimeSpanType sufficient_accuracy) - public ResultCode SetupStandardNetworkSystemClock(ServiceCtx context) - { - SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>(); - TimeSpanType sufficientAccuracy = context.RequestData.ReadStruct<TimeSpanType>(); - - _timeManager.SetupStandardNetworkSystemClock(clockContext, sufficientAccuracy); - - return ResultCode.Success; - } - - [CommandCmif(13)] - // SetupStandardUserSystemClock(bool automatic_correction_enabled, nn::time::SteadyClockTimePoint steady_clock_timepoint) - public ResultCode SetupStandardUserSystemClock(ServiceCtx context) - { - bool isAutomaticCorrectionEnabled = context.RequestData.ReadBoolean(); - - context.RequestData.BaseStream.Position += 7; - - SteadyClockTimePoint steadyClockTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>(); - - ITickSource tickSource = context.Device.System.TickSource; - - _timeManager.SetupStandardUserSystemClock(tickSource, isAutomaticCorrectionEnabled, steadyClockTimePoint); - - return ResultCode.Success; - } - - [CommandCmif(14)] - // SetupTimeZoneManager(nn::time::LocationName location_name, nn::time::SteadyClockTimePoint timezone_update_timepoint, u32 total_location_name_count, nn::time::TimeZoneRuleVersion timezone_rule_version, buffer<nn::time::TimeZoneBinary, 0x21> timezone_binary) - public ResultCode SetupTimeZoneManager(ServiceCtx context) - { - string locationName = StringUtils.ReadInlinedAsciiString(context.RequestData, 0x24); - SteadyClockTimePoint timeZoneUpdateTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>(); - uint totalLocationNameCount = context.RequestData.ReadUInt32(); - UInt128 timeZoneRuleVersion = context.RequestData.ReadStruct<UInt128>(); - - (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(); - - byte[] temp = new byte[bufferSize]; - - context.Memory.Read(bufferPosition, temp); - - using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp)) - { - _timeManager.SetupTimeZoneManager(locationName, timeZoneUpdateTimePoint, totalLocationNameCount, timeZoneRuleVersion, timeZoneBinaryStream); - } - - return ResultCode.Success; - } - - [CommandCmif(15)] - // SetupEphemeralNetworkSystemClock() - public ResultCode SetupEphemeralNetworkSystemClock(ServiceCtx context) - { - _timeManager.SetupEphemeralNetworkSystemClock(); - - return ResultCode.Success; - } - - [CommandCmif(50)] - // Unknown50() -> handle<copy> - public ResultCode Unknown50(ServiceCtx context) - { - // TODO: figure out the usage of this event - throw new ServiceNotImplementedException(this, context); - } - - [CommandCmif(51)] - // Unknown51() -> handle<copy> - public ResultCode Unknown51(ServiceCtx context) - { - // TODO: figure out the usage of this event - throw new ServiceNotImplementedException(this, context); - } - - [CommandCmif(52)] - // Unknown52() -> handle<copy> - public ResultCode Unknown52(ServiceCtx context) - { - // TODO: figure out the usage of this event - throw new ServiceNotImplementedException(this, context); - } - - [CommandCmif(60)] - // GetStandardUserSystemClockAutomaticCorrectionEvent() -> handle<copy> - public ResultCode GetStandardUserSystemClockAutomaticCorrectionEvent(ServiceCtx context) - { - if (_automaticCorrectionEvent == 0) - { - if (context.Process.HandleTable.GenerateHandle(_timeManager.StandardUserSystemClock.GetAutomaticCorrectionReadableEvent(), out _automaticCorrectionEvent) != Result.Success) - { - throw new InvalidOperationException("Out of handles!"); - } - } - - context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_automaticCorrectionEvent); - - return ResultCode.Success; - } - - [CommandCmif(100)] - // SetStandardSteadyClockRtcOffset(nn::TimeSpanType rtc_offset) - public ResultCode SetStandardSteadyClockRtcOffset(ServiceCtx context) - { - TimeSpanType rtcOffset = context.RequestData.ReadStruct<TimeSpanType>(); - - ITickSource tickSource = context.Device.System.TickSource; - - _timeManager.SetStandardSteadyClockRtcOffset(tickSource, rtcOffset); - - return ResultCode.Success; - } - - [CommandCmif(200)] - // GetAlarmRegistrationEvent() -> handle<copy> - public ResultCode GetAlarmRegistrationEvent(ServiceCtx context) - { - // TODO - throw new ServiceNotImplementedException(this, context); - } - - [CommandCmif(201)] - // UpdateSteadyAlarms() - public ResultCode UpdateSteadyAlarms(ServiceCtx context) - { - // TODO - throw new ServiceNotImplementedException(this, context); - } - - [CommandCmif(202)] - // TryGetNextSteadyClockAlarmSnapshot() -> (bool, nn::time::SteadyClockAlarmSnapshot) - public ResultCode TryGetNextSteadyClockAlarmSnapshot(ServiceCtx context) - { - // TODO - throw new ServiceNotImplementedException(this, context); - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs deleted file mode 100644 index 3b042ec0..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Time -{ - public enum ResultCode - { - ModuleId = 116, - ErrorCodeShift = 9, - - Success = 0, - - TimeServiceNotInitialized = (0 << ErrorCodeShift) | ModuleId, - PermissionDenied = (1 << ErrorCodeShift) | ModuleId, - TimeMismatch = (102 << ErrorCodeShift) | ModuleId, - UninitializedClock = (103 << ErrorCodeShift) | ModuleId, - TimeNotFound = (200 << ErrorCodeShift) | ModuleId, - Overflow = (201 << ErrorCodeShift) | ModuleId, - LocationNameTooLong = (801 << ErrorCodeShift) | ModuleId, - OutOfRange = (902 << ErrorCodeShift) | ModuleId, - TimeZoneConversionFailed = (903 << ErrorCodeShift) | ModuleId, - TimeZoneNotFound = (989 << ErrorCodeShift) | ModuleId, - NotImplemented = (990 << ErrorCodeShift) | ModuleId, - NetworkTimeNotAvailable = (1000 << ErrorCodeShift) | ModuleId, - NetworkTimeTaskCanceled = (1003 << ErrorCodeShift) | ModuleId, - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/StaticService/ISteadyClock.cs b/Ryujinx.HLE/HOS/Services/Time/StaticService/ISteadyClock.cs deleted file mode 100644 index 97d7884e..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/StaticService/ISteadyClock.cs +++ /dev/null @@ -1,155 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Cpu; -using Ryujinx.HLE.HOS.Services.Time.Clock; - -namespace Ryujinx.HLE.HOS.Services.Time.StaticService -{ - class ISteadyClock : IpcService - { - private SteadyClockCore _steadyClock; - private bool _writePermission; - private bool _bypassUninitializedClock; - - public ISteadyClock(SteadyClockCore steadyClock, bool writePermission, bool bypassUninitializedClock) - { - _steadyClock = steadyClock; - _writePermission = writePermission; - _bypassUninitializedClock = bypassUninitializedClock; - } - - [CommandCmif(0)] - // GetCurrentTimePoint() -> nn::time::SteadyClockTimePoint - public ResultCode GetCurrentTimePoint(ServiceCtx context) - { - if (!_bypassUninitializedClock && !_steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - ITickSource tickSource = context.Device.System.TickSource; - - SteadyClockTimePoint currentTimePoint = _steadyClock.GetCurrentTimePoint(tickSource); - - context.ResponseData.WriteStruct(currentTimePoint); - - return ResultCode.Success; - } - - [CommandCmif(2)] - // GetTestOffset() -> nn::TimeSpanType - public ResultCode GetTestOffset(ServiceCtx context) - { - if (!_bypassUninitializedClock && !_steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - context.ResponseData.WriteStruct(_steadyClock.GetTestOffset()); - - return ResultCode.Success; - } - - [CommandCmif(3)] - // SetTestOffset(nn::TimeSpanType) - public ResultCode SetTestOffset(ServiceCtx context) - { - if (!_writePermission) - { - return ResultCode.PermissionDenied; - } - - if (!_bypassUninitializedClock && !_steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - TimeSpanType testOffset = context.RequestData.ReadStruct<TimeSpanType>(); - - _steadyClock.SetTestOffset(testOffset); - - return ResultCode.Success; - } - - [CommandCmif(100)] // 2.0.0+ - // GetRtcValue() -> u64 - public ResultCode GetRtcValue(ServiceCtx context) - { - if (!_bypassUninitializedClock && !_steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - ResultCode result = _steadyClock.GetRtcValue(out ulong rtcValue); - - if (result == ResultCode.Success) - { - context.ResponseData.Write(rtcValue); - } - - return result; - } - - [CommandCmif(101)] // 2.0.0+ - // IsRtcResetDetected() -> bool - public ResultCode IsRtcResetDetected(ServiceCtx context) - { - if (!_bypassUninitializedClock && !_steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - context.ResponseData.Write(_steadyClock.IsRtcResetDetected()); - - return ResultCode.Success; - } - - [CommandCmif(102)] // 2.0.0+ - // GetSetupResultValue() -> u32 - public ResultCode GetSetupResultValue(ServiceCtx context) - { - if (!_bypassUninitializedClock && !_steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - context.ResponseData.Write((uint)_steadyClock.GetSetupResultValue()); - - return ResultCode.Success; - } - - [CommandCmif(200)] // 3.0.0+ - // GetInternalOffset() -> nn::TimeSpanType - public ResultCode GetInternalOffset(ServiceCtx context) - { - if (!_bypassUninitializedClock && !_steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - context.ResponseData.WriteStruct(_steadyClock.GetInternalOffset()); - - return ResultCode.Success; - } - - [CommandCmif(201)] // 3.0.0-3.0.2 - // SetInternalOffset(nn::TimeSpanType) - public ResultCode SetInternalOffset(ServiceCtx context) - { - if (!_writePermission) - { - return ResultCode.PermissionDenied; - } - - if (!_bypassUninitializedClock && !_steadyClock.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - TimeSpanType internalOffset = context.RequestData.ReadStruct<TimeSpanType>(); - - _steadyClock.SetInternalOffset(internalOffset); - - return ResultCode.Success; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/StaticService/ISystemClock.cs b/Ryujinx.HLE/HOS/Services/Time/StaticService/ISystemClock.cs deleted file mode 100644 index 3cd0a4a6..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/StaticService/ISystemClock.cs +++ /dev/null @@ -1,131 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Cpu; -using Ryujinx.HLE.HOS.Ipc; -using Ryujinx.HLE.HOS.Kernel.Threading; -using Ryujinx.HLE.HOS.Services.Time.Clock; -using Ryujinx.Horizon.Common; -using System; - -namespace Ryujinx.HLE.HOS.Services.Time.StaticService -{ - class ISystemClock : IpcService - { - private SystemClockCore _clockCore; - private bool _writePermission; - private bool _bypassUninitializedClock; - private int _operationEventReadableHandle; - - public ISystemClock(SystemClockCore clockCore, bool writePermission, bool bypassUninitializedClock) - { - _clockCore = clockCore; - _writePermission = writePermission; - _bypassUninitializedClock = bypassUninitializedClock; - _operationEventReadableHandle = 0; - } - - [CommandCmif(0)] - // GetCurrentTime() -> nn::time::PosixTime - public ResultCode GetCurrentTime(ServiceCtx context) - { - if (!_bypassUninitializedClock && !_clockCore.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - ITickSource tickSource = context.Device.System.TickSource; - - ResultCode result = _clockCore.GetCurrentTime(tickSource, out long posixTime); - - if (result == ResultCode.Success) - { - context.ResponseData.Write(posixTime); - } - - return result; - } - - [CommandCmif(1)] - // SetCurrentTime(nn::time::PosixTime) - public ResultCode SetCurrentTime(ServiceCtx context) - { - if (!_writePermission) - { - return ResultCode.PermissionDenied; - } - - if (!_bypassUninitializedClock && !_clockCore.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - long posixTime = context.RequestData.ReadInt64(); - - ITickSource tickSource = context.Device.System.TickSource; - - return _clockCore.SetCurrentTime(tickSource, posixTime); - } - - [CommandCmif(2)] - // GetClockContext() -> nn::time::SystemClockContext - public ResultCode GetSystemClockContext(ServiceCtx context) - { - if (!_bypassUninitializedClock && !_clockCore.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - ITickSource tickSource = context.Device.System.TickSource; - - ResultCode result = _clockCore.GetClockContext(tickSource, out SystemClockContext clockContext); - - if (result == ResultCode.Success) - { - context.ResponseData.WriteStruct(clockContext); - } - - return result; - } - - [CommandCmif(3)] - // SetClockContext(nn::time::SystemClockContext) - public ResultCode SetSystemClockContext(ServiceCtx context) - { - if (!_writePermission) - { - return ResultCode.PermissionDenied; - } - - if (!_bypassUninitializedClock && !_clockCore.IsInitialized()) - { - return ResultCode.UninitializedClock; - } - - SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>(); - - ResultCode result = _clockCore.SetSystemClockContext(clockContext); - - return result; - } - - [CommandCmif(4)] // 9.0.0+ - // GetOperationEventReadableHandle() -> handle<copy> - public ResultCode GetOperationEventReadableHandle(ServiceCtx context) - { - if (_operationEventReadableHandle == 0) - { - KEvent kEvent = new KEvent(context.Device.System.KernelContext); - - _clockCore.RegisterOperationEvent(kEvent.WritableEvent); - - if (context.Process.HandleTable.GenerateHandle(kEvent.ReadableEvent, out _operationEventReadableHandle) != Result.Success) - { - throw new InvalidOperationException("Out of handles!"); - } - } - - context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_operationEventReadableHandle); - - return ResultCode.Success; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs b/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs deleted file mode 100644 index 96a7e604..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForGlue.cs +++ /dev/null @@ -1,142 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Cpu; -using Ryujinx.HLE.HOS.Services.Time.TimeZone; -using Ryujinx.HLE.Utilities; -using Ryujinx.Memory; -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -namespace Ryujinx.HLE.HOS.Services.Time.StaticService -{ - class ITimeZoneServiceForGlue : IpcService - { - private TimeZoneContentManager _timeZoneContentManager; - private ITimeZoneServiceForPsc _inner; - private bool _writePermission; - - public ITimeZoneServiceForGlue(TimeZoneContentManager timeZoneContentManager, bool writePermission) - { - _timeZoneContentManager = timeZoneContentManager; - _writePermission = writePermission; - _inner = new ITimeZoneServiceForPsc(timeZoneContentManager.Manager, writePermission); - } - - [CommandCmif(0)] - // GetDeviceLocationName() -> nn::time::LocationName - public ResultCode GetDeviceLocationName(ServiceCtx context) - { - return _inner.GetDeviceLocationName(context); - } - - [CommandCmif(1)] - // SetDeviceLocationName(nn::time::LocationName) - public ResultCode SetDeviceLocationName(ServiceCtx context) - { - if (!_writePermission) - { - return ResultCode.PermissionDenied; - } - - string locationName = StringUtils.ReadInlinedAsciiString(context.RequestData, 0x24); - - return _timeZoneContentManager.SetDeviceLocationName(locationName); - } - - [CommandCmif(2)] - // GetTotalLocationNameCount() -> u32 - public ResultCode GetTotalLocationNameCount(ServiceCtx context) - { - return _inner.GetTotalLocationNameCount(context); - } - - [CommandCmif(3)] - // LoadLocationNameList(u32 index) -> (u32 outCount, buffer<nn::time::LocationName, 6>) - public ResultCode LoadLocationNameList(ServiceCtx context) - { - uint index = context.RequestData.ReadUInt32(); - ulong bufferPosition = context.Request.ReceiveBuff[0].Position; - ulong bufferSize = context.Request.ReceiveBuff[0].Size; - - ResultCode errorCode = _timeZoneContentManager.LoadLocationNameList(index, out string[] locationNameArray, (uint)bufferSize / 0x24); - - if (errorCode == 0) - { - uint offset = 0; - - foreach (string locationName in locationNameArray) - { - int padding = 0x24 - locationName.Length; - - if (padding < 0) - { - return ResultCode.LocationNameTooLong; - } - - context.Memory.Write(bufferPosition + offset, Encoding.ASCII.GetBytes(locationName)); - MemoryHelper.FillWithZeros(context.Memory, bufferPosition + offset + (ulong)locationName.Length, padding); - - offset += 0x24; - } - - context.ResponseData.Write((uint)locationNameArray.Length); - } - - return errorCode; - } - - [CommandCmif(4)] - // LoadTimeZoneRule(nn::time::LocationName locationName) -> buffer<nn::time::TimeZoneRule, 0x16> - public ResultCode LoadTimeZoneRule(ServiceCtx context) - { - ulong bufferPosition = context.Request.ReceiveBuff[0].Position; - ulong bufferSize = context.Request.ReceiveBuff[0].Size; - - if (bufferSize != 0x4000) - { - // TODO: find error code here - Logger.Error?.Print(LogClass.ServiceTime, $"TimeZoneRule buffer size is 0x{bufferSize:x} (expected 0x4000)"); - - throw new InvalidOperationException(); - } - - string locationName = StringUtils.ReadInlinedAsciiString(context.RequestData, 0x24); - - using (WritableRegion region = context.Memory.GetWritableRegion(bufferPosition, Unsafe.SizeOf<TimeZoneRule>())) - { - ref TimeZoneRule rules = ref MemoryMarshal.Cast<byte, TimeZoneRule>(region.Memory.Span)[0]; - - return _timeZoneContentManager.LoadTimeZoneRule(ref rules, locationName); - } - } - - [CommandCmif(100)] - // ToCalendarTime(nn::time::PosixTime time, buffer<nn::time::TimeZoneRule, 0x15> rules) -> (nn::time::CalendarTime, nn::time::sf::CalendarAdditionalInfo) - public ResultCode ToCalendarTime(ServiceCtx context) - { - return _inner.ToCalendarTime(context); - } - - [CommandCmif(101)] - // ToCalendarTimeWithMyRule(nn::time::PosixTime) -> (nn::time::CalendarTime, nn::time::sf::CalendarAdditionalInfo) - public ResultCode ToCalendarTimeWithMyRule(ServiceCtx context) - { - return _inner.ToCalendarTimeWithMyRule(context); - } - - [CommandCmif(201)] - // ToPosixTime(nn::time::CalendarTime calendarTime, buffer<nn::time::TimeZoneRule, 0x15> rules) -> (u32 outCount, buffer<nn::time::PosixTime, 0xa>) - public ResultCode ToPosixTime(ServiceCtx context) - { - return _inner.ToPosixTime(context); - } - - [CommandCmif(202)] - // ToPosixTimeWithMyRule(nn::time::CalendarTime calendarTime) -> (u32 outCount, buffer<nn::time::PosixTime, 0xa>) - public ResultCode ToPosixTimeWithMyRule(ServiceCtx context) - { - return _inner.ToPosixTimeWithMyRule(context); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs b/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs deleted file mode 100644 index 3c9ac71f..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/StaticService/ITimeZoneServiceForPsc.cs +++ /dev/null @@ -1,303 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Common.Logging; -using Ryujinx.HLE.HOS.Services.Time.Clock; -using Ryujinx.HLE.HOS.Services.Time.TimeZone; -using Ryujinx.HLE.Utilities; -using Ryujinx.Memory; -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.StaticService -{ - class ITimeZoneServiceForPsc : IpcService - { - private TimeZoneManager _timeZoneManager; - private bool _writePermission; - - public ITimeZoneServiceForPsc(TimeZoneManager timeZoneManager, bool writePermission) - { - _timeZoneManager = timeZoneManager; - _writePermission = writePermission; - } - - [CommandCmif(0)] - // GetDeviceLocationName() -> nn::time::LocationName - public ResultCode GetDeviceLocationName(ServiceCtx context) - { - ResultCode result = _timeZoneManager.GetDeviceLocationName(out string deviceLocationName); - - if (result == ResultCode.Success) - { - WriteLocationName(context, deviceLocationName); - } - - return result; - } - - [CommandCmif(1)] - // SetDeviceLocationName(nn::time::LocationName) - public ResultCode SetDeviceLocationName(ServiceCtx context) - { - if (!_writePermission) - { - return ResultCode.PermissionDenied; - } - - return ResultCode.NotImplemented; - } - - [CommandCmif(2)] - // GetTotalLocationNameCount() -> u32 - public ResultCode GetTotalLocationNameCount(ServiceCtx context) - { - ResultCode result = _timeZoneManager.GetTotalLocationNameCount(out uint totalLocationNameCount); - - if (result == ResultCode.Success) - { - context.ResponseData.Write(totalLocationNameCount); - } - - return ResultCode.Success; - } - - [CommandCmif(3)] - // LoadLocationNameList(u32 index) -> (u32 outCount, buffer<nn::time::LocationName, 6>) - public ResultCode LoadLocationNameList(ServiceCtx context) - { - return ResultCode.NotImplemented; - } - - [CommandCmif(4)] - // LoadTimeZoneRule(nn::time::LocationName locationName) -> buffer<nn::time::TimeZoneRule, 0x16> - public ResultCode LoadTimeZoneRule(ServiceCtx context) - { - return ResultCode.NotImplemented; - } - - [CommandCmif(5)] // 2.0.0+ - // GetTimeZoneRuleVersion() -> nn::time::TimeZoneRuleVersion - public ResultCode GetTimeZoneRuleVersion(ServiceCtx context) - { - ResultCode result = _timeZoneManager.GetTimeZoneRuleVersion(out UInt128 timeZoneRuleVersion); - - if (result == ResultCode.Success) - { - context.ResponseData.WriteStruct(timeZoneRuleVersion); - } - - return result; - } - - [CommandCmif(6)] // 5.0.0+ - // GetDeviceLocationNameAndUpdatedTime() -> (nn::time::LocationName, nn::time::SteadyClockTimePoint) - public ResultCode GetDeviceLocationNameAndUpdatedTime(ServiceCtx context) - { - ResultCode result = _timeZoneManager.GetDeviceLocationName(out string deviceLocationName); - - if (result == ResultCode.Success) - { - result = _timeZoneManager.GetUpdatedTime(out SteadyClockTimePoint timeZoneUpdateTimePoint); - - if (result == ResultCode.Success) - { - WriteLocationName(context, deviceLocationName); - - // Skip padding - context.ResponseData.BaseStream.Position += 0x4; - - context.ResponseData.WriteStruct(timeZoneUpdateTimePoint); - } - } - - return result; - } - - [CommandCmif(7)] // 9.0.0+ - // SetDeviceLocationNameWithTimeZoneRule(nn::time::LocationName locationName, buffer<nn::time::TimeZoneBinary, 0x21> timeZoneBinary) - public ResultCode SetDeviceLocationNameWithTimeZoneRule(ServiceCtx context) - { - if (!_writePermission) - { - return ResultCode.PermissionDenied; - } - - (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(); - - string locationName = StringUtils.ReadInlinedAsciiString(context.RequestData, 0x24); - - ResultCode result; - - byte[] temp = new byte[bufferSize]; - - context.Memory.Read(bufferPosition, temp); - - using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp)) - { - result = _timeZoneManager.SetDeviceLocationNameWithTimeZoneRule(locationName, timeZoneBinaryStream); - } - - return result; - } - - [CommandCmif(8)] // 9.0.0+ - // ParseTimeZoneBinary(buffer<nn::time::TimeZoneBinary, 0x21> timeZoneBinary) -> buffer<nn::time::TimeZoneRule, 0x16> - public ResultCode ParseTimeZoneBinary(ServiceCtx context) - { - (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(); - - ulong timeZoneRuleBufferPosition = context.Request.ReceiveBuff[0].Position; - ulong timeZoneRuleBufferSize = context.Request.ReceiveBuff[0].Size; - - if (timeZoneRuleBufferSize != 0x4000) - { - // TODO: find error code here - Logger.Error?.Print(LogClass.ServiceTime, $"TimeZoneRule buffer size is 0x{timeZoneRuleBufferSize:x} (expected 0x4000)"); - - throw new InvalidOperationException(); - } - - ResultCode result; - - byte[] temp = new byte[bufferSize]; - - context.Memory.Read(bufferPosition, temp); - - using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp)) - { - using (WritableRegion region = context.Memory.GetWritableRegion(timeZoneRuleBufferPosition, Unsafe.SizeOf<TimeZoneRule>())) - { - ref TimeZoneRule rule = ref MemoryMarshal.Cast<byte, TimeZoneRule>(region.Memory.Span)[0]; - - result = _timeZoneManager.ParseTimeZoneRuleBinary(ref rule, timeZoneBinaryStream); - } - } - - return result; - } - - [CommandCmif(20)] // 9.0.0+ - // GetDeviceLocationNameOperationEventReadableHandle() -> handle<copy> - public ResultCode GetDeviceLocationNameOperationEventReadableHandle(ServiceCtx context) - { - return ResultCode.NotImplemented; - } - - [CommandCmif(100)] - // ToCalendarTime(nn::time::PosixTime time, buffer<nn::time::TimeZoneRule, 0x15> rules) -> (nn::time::CalendarTime, nn::time::sf::CalendarAdditionalInfo) - public ResultCode ToCalendarTime(ServiceCtx context) - { - long posixTime = context.RequestData.ReadInt64(); - ulong bufferPosition = context.Request.SendBuff[0].Position; - ulong bufferSize = context.Request.SendBuff[0].Size; - - if (bufferSize != 0x4000) - { - // TODO: find error code here - Logger.Error?.Print(LogClass.ServiceTime, $"TimeZoneRule buffer size is 0x{bufferSize:x} (expected 0x4000)"); - - throw new InvalidOperationException(); - } - - ReadOnlySpan<TimeZoneRule> rules = MemoryMarshal.Cast<byte, TimeZoneRule>(context.Memory.GetSpan(bufferPosition, (int)bufferSize)); - - ResultCode resultCode = _timeZoneManager.ToCalendarTime(in rules[0], posixTime, out CalendarInfo calendar); - - if (resultCode == 0) - { - context.ResponseData.WriteStruct(calendar); - } - - return resultCode; - } - - [CommandCmif(101)] - // ToCalendarTimeWithMyRule(nn::time::PosixTime) -> (nn::time::CalendarTime, nn::time::sf::CalendarAdditionalInfo) - public ResultCode ToCalendarTimeWithMyRule(ServiceCtx context) - { - long posixTime = context.RequestData.ReadInt64(); - - ResultCode resultCode = _timeZoneManager.ToCalendarTimeWithMyRules(posixTime, out CalendarInfo calendar); - - if (resultCode == ResultCode.Success) - { - context.ResponseData.WriteStruct(calendar); - } - - return resultCode; - } - - [CommandCmif(201)] - // ToPosixTime(nn::time::CalendarTime calendarTime, buffer<nn::time::TimeZoneRule, 0x15> rules) -> (u32 outCount, buffer<nn::time::PosixTime, 0xa>) - public ResultCode ToPosixTime(ServiceCtx context) - { - ulong inBufferPosition = context.Request.SendBuff[0].Position; - ulong inBufferSize = context.Request.SendBuff[0].Size; - - CalendarTime calendarTime = context.RequestData.ReadStruct<CalendarTime>(); - - if (inBufferSize != 0x4000) - { - // TODO: find error code here - Logger.Error?.Print(LogClass.ServiceTime, $"TimeZoneRule buffer size is 0x{inBufferSize:x} (expected 0x4000)"); - - throw new InvalidOperationException(); - } - - ReadOnlySpan<TimeZoneRule> rules = MemoryMarshal.Cast<byte, TimeZoneRule>(context.Memory.GetSpan(inBufferPosition, (int)inBufferSize)); - - ResultCode resultCode = _timeZoneManager.ToPosixTime(in rules[0], calendarTime, out long posixTime); - - if (resultCode == ResultCode.Success) - { - ulong outBufferPosition = context.Request.RecvListBuff[0].Position; - ulong outBufferSize = context.Request.RecvListBuff[0].Size; - - context.Memory.Write(outBufferPosition, posixTime); - context.ResponseData.Write(1); - } - - return resultCode; - } - - [CommandCmif(202)] - // ToPosixTimeWithMyRule(nn::time::CalendarTime calendarTime) -> (u32 outCount, buffer<nn::time::PosixTime, 0xa>) - public ResultCode ToPosixTimeWithMyRule(ServiceCtx context) - { - CalendarTime calendarTime = context.RequestData.ReadStruct<CalendarTime>(); - - ResultCode resultCode = _timeZoneManager.ToPosixTimeWithMyRules(calendarTime, out long posixTime); - - if (resultCode == ResultCode.Success) - { - ulong outBufferPosition = context.Request.RecvListBuff[0].Position; - ulong outBufferSize = context.Request.RecvListBuff[0].Size; - - context.Memory.Write(outBufferPosition, posixTime); - - // There could be only one result on one calendar as leap seconds aren't supported. - context.ResponseData.Write(1); - } - - return resultCode; - } - - private void WriteLocationName(ServiceCtx context, string locationName) - { - char[] locationNameArray = locationName.ToCharArray(); - - int padding = 0x24 - locationNameArray.Length; - - Debug.Assert(padding >= 0, "LocationName exceeded limit (0x24 bytes)"); - - context.ResponseData.Write(locationNameArray); - - for (int index = 0; index < padding; index++) - { - context.ResponseData.Write((byte)0); - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeManager.cs b/Ryujinx.HLE/HOS/Services/Time/TimeManager.cs deleted file mode 100644 index e3b65f2a..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeManager.cs +++ /dev/null @@ -1,182 +0,0 @@ -using Ryujinx.Cpu; -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Kernel.Memory; -using Ryujinx.HLE.HOS.Services.Time.Clock; -using Ryujinx.HLE.HOS.Services.Time.TimeZone; -using System; -using System.IO; - -namespace Ryujinx.HLE.HOS.Services.Time -{ - class TimeManager - { - private static TimeManager _instance; - - public static TimeManager Instance - { - get - { - if (_instance == null) - { - _instance = new TimeManager(); - } - - return _instance; - } - } - - public StandardSteadyClockCore StandardSteadyClock { get; } - public TickBasedSteadyClockCore TickBasedSteadyClock { get; } - public StandardLocalSystemClockCore StandardLocalSystemClock { get; } - public StandardNetworkSystemClockCore StandardNetworkSystemClock { get; } - public StandardUserSystemClockCore StandardUserSystemClock { get; } - public TimeZoneContentManager TimeZone { get; } - public EphemeralNetworkSystemClockCore EphemeralNetworkSystemClock { get; } - public TimeSharedMemory SharedMemory { get; } - public LocalSystemClockContextWriter LocalClockContextWriter { get; } - public NetworkSystemClockContextWriter NetworkClockContextWriter { get; } - public EphemeralNetworkSystemClockContextWriter EphemeralClockContextWriter { get; } - - // TODO: 9.0.0+ power states and alarms - - public TimeManager() - { - StandardSteadyClock = new StandardSteadyClockCore(); - TickBasedSteadyClock = new TickBasedSteadyClockCore(); - StandardLocalSystemClock = new StandardLocalSystemClockCore(StandardSteadyClock); - StandardNetworkSystemClock = new StandardNetworkSystemClockCore(StandardSteadyClock); - StandardUserSystemClock = new StandardUserSystemClockCore(StandardLocalSystemClock, StandardNetworkSystemClock); - TimeZone = new TimeZoneContentManager(); - EphemeralNetworkSystemClock = new EphemeralNetworkSystemClockCore(TickBasedSteadyClock); - SharedMemory = new TimeSharedMemory(); - LocalClockContextWriter = new LocalSystemClockContextWriter(SharedMemory); - NetworkClockContextWriter = new NetworkSystemClockContextWriter(SharedMemory); - EphemeralClockContextWriter = new EphemeralNetworkSystemClockContextWriter(); - } - - public void Initialize(Switch device, Horizon system, KSharedMemory sharedMemory, SharedMemoryStorage timeSharedMemoryStorage, int timeSharedMemorySize) - { - SharedMemory.Initialize(device, sharedMemory, timeSharedMemoryStorage, timeSharedMemorySize); - - // Here we use system on purpose as device. System isn't initialized at this point. - StandardUserSystemClock.CreateAutomaticCorrectionEvent(system); - } - - public void InitializeTimeZone(Switch device) - { - TimeZone.Initialize(this, device); - } - - public void SetupStandardSteadyClock(ITickSource tickSource, UInt128 clockSourceId, TimeSpanType setupValue, TimeSpanType internalOffset, TimeSpanType testOffset, bool isRtcResetDetected) - { - SetupInternalStandardSteadyClock(clockSourceId, setupValue, internalOffset, testOffset, isRtcResetDetected); - - TimeSpanType currentTimePoint = StandardSteadyClock.GetCurrentRawTimePoint(tickSource); - - SharedMemory.SetupStandardSteadyClock(tickSource, clockSourceId, currentTimePoint); - - // TODO: propagate IPC late binding of "time:s" and "time:p" - } - - private void SetupInternalStandardSteadyClock(UInt128 clockSourceId, TimeSpanType setupValue, TimeSpanType internalOffset, TimeSpanType testOffset, bool isRtcResetDetected) - { - StandardSteadyClock.SetClockSourceId(clockSourceId); - StandardSteadyClock.SetSetupValue(setupValue); - StandardSteadyClock.SetInternalOffset(internalOffset); - StandardSteadyClock.SetTestOffset(testOffset); - - if (isRtcResetDetected) - { - StandardSteadyClock.SetRtcReset(); - } - - StandardSteadyClock.MarkInitialized(); - - // TODO: propagate IPC late binding of "time:s" and "time:p" - } - - public void SetupStandardLocalSystemClock(ITickSource tickSource, SystemClockContext clockContext, long posixTime) - { - StandardLocalSystemClock.SetUpdateCallbackInstance(LocalClockContextWriter); - - SteadyClockTimePoint currentTimePoint = StandardLocalSystemClock.GetSteadyClockCore().GetCurrentTimePoint(tickSource); - if (currentTimePoint.ClockSourceId == clockContext.SteadyTimePoint.ClockSourceId) - { - StandardLocalSystemClock.SetSystemClockContext(clockContext); - } - else - { - if (StandardLocalSystemClock.SetCurrentTime(tickSource, posixTime) != ResultCode.Success) - { - throw new InternalServiceException("Cannot set current local time"); - } - } - - StandardLocalSystemClock.MarkInitialized(); - - // TODO: propagate IPC late binding of "time:s" and "time:p" - } - - public void SetupStandardNetworkSystemClock(SystemClockContext clockContext, TimeSpanType sufficientAccuracy) - { - StandardNetworkSystemClock.SetUpdateCallbackInstance(NetworkClockContextWriter); - - if (StandardNetworkSystemClock.SetSystemClockContext(clockContext) != ResultCode.Success) - { - throw new InternalServiceException("Cannot set network SystemClockContext"); - } - - StandardNetworkSystemClock.SetStandardNetworkClockSufficientAccuracy(sufficientAccuracy); - StandardNetworkSystemClock.MarkInitialized(); - - // TODO: propagate IPC late binding of "time:s" and "time:p" - } - - public void SetupTimeZoneManager(string locationName, SteadyClockTimePoint timeZoneUpdatedTimePoint, uint totalLocationNameCount, UInt128 timeZoneRuleVersion, Stream timeZoneBinaryStream) - { - if (TimeZone.Manager.SetDeviceLocationNameWithTimeZoneRule(locationName, timeZoneBinaryStream) != ResultCode.Success) - { - throw new InternalServiceException("Cannot set DeviceLocationName with a given TimeZoneBinary"); - } - - TimeZone.Manager.SetUpdatedTime(timeZoneUpdatedTimePoint, true); - TimeZone.Manager.SetTotalLocationNameCount(totalLocationNameCount); - TimeZone.Manager.SetTimeZoneRuleVersion(timeZoneRuleVersion); - TimeZone.Manager.MarkInitialized(); - - // TODO: propagate IPC late binding of "time:s" and "time:p" - } - - public void SetupEphemeralNetworkSystemClock() - { - EphemeralNetworkSystemClock.SetUpdateCallbackInstance(EphemeralClockContextWriter); - EphemeralNetworkSystemClock.MarkInitialized(); - - // TODO: propagate IPC late binding of "time:s" and "time:p" - } - - public void SetupStandardUserSystemClock(ITickSource tickSource, bool isAutomaticCorrectionEnabled, SteadyClockTimePoint steadyClockTimePoint) - { - if (StandardUserSystemClock.SetAutomaticCorrectionEnabled(tickSource, isAutomaticCorrectionEnabled) != ResultCode.Success) - { - throw new InternalServiceException("Cannot set automatic user time correction state"); - } - - StandardUserSystemClock.SetAutomaticCorrectionUpdatedTime(steadyClockTimePoint); - StandardUserSystemClock.MarkInitialized(); - - SharedMemory.SetAutomaticCorrectionEnabled(isAutomaticCorrectionEnabled); - - // TODO: propagate IPC late binding of "time:s" and "time:p" - } - - public void SetStandardSteadyClockRtcOffset(ITickSource tickSource, TimeSpanType rtcOffset) - { - StandardSteadyClock.SetSetupValue(rtcOffset); - - TimeSpanType currentTimePoint = StandardSteadyClock.GetCurrentRawTimePoint(tickSource); - - SharedMemory.SetSteadyClockRawTimePoint(tickSource, currentTimePoint); - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeSharedMemory.cs b/Ryujinx.HLE/HOS/Services/Time/TimeSharedMemory.cs deleted file mode 100644 index 7063290b..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeSharedMemory.cs +++ /dev/null @@ -1,114 +0,0 @@ -using Ryujinx.Cpu; -using Ryujinx.HLE.HOS.Kernel.Memory; -using Ryujinx.HLE.HOS.Services.Time.Clock; -using Ryujinx.HLE.HOS.Services.Time.Types; -using Ryujinx.HLE.Utilities; -using System; -using System.Runtime.CompilerServices; -using System.Threading; - -namespace Ryujinx.HLE.HOS.Services.Time -{ - class TimeSharedMemory - { - private Switch _device; - private KSharedMemory _sharedMemory; - private SharedMemoryStorage _timeSharedMemoryStorage; - private int _timeSharedMemorySize; - - private const uint SteadyClockContextOffset = 0x00; - private const uint LocalSystemClockContextOffset = 0x38; - private const uint NetworkSystemClockContextOffset = 0x80; - private const uint AutomaticCorrectionEnabledOffset = 0xC8; - - public void Initialize(Switch device, KSharedMemory sharedMemory, SharedMemoryStorage timeSharedMemoryStorage, int timeSharedMemorySize) - { - _device = device; - _sharedMemory = sharedMemory; - _timeSharedMemoryStorage = timeSharedMemoryStorage; - _timeSharedMemorySize = timeSharedMemorySize; - - // Clean the shared memory - timeSharedMemoryStorage.ZeroFill(); - } - - public KSharedMemory GetSharedMemory() - { - return _sharedMemory; - } - - public void SetupStandardSteadyClock(ITickSource tickSource, UInt128 clockSourceId, TimeSpanType currentTimePoint) - { - TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency); - - SteadyClockContext context = new SteadyClockContext - { - InternalOffset = (ulong)(currentTimePoint.NanoSeconds - ticksTimeSpan.NanoSeconds), - ClockSourceId = clockSourceId - }; - - WriteObjectToSharedMemory(SteadyClockContextOffset, 4, context); - } - - public void SetAutomaticCorrectionEnabled(bool isAutomaticCorrectionEnabled) - { - // We convert the bool to byte here as a bool in C# takes 4 bytes... - WriteObjectToSharedMemory(AutomaticCorrectionEnabledOffset, 0, Convert.ToByte(isAutomaticCorrectionEnabled)); - } - - public void SetSteadyClockRawTimePoint(ITickSource tickSource, TimeSpanType currentTimePoint) - { - SteadyClockContext context = ReadObjectFromSharedMemory<SteadyClockContext>(SteadyClockContextOffset, 4); - TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency); - - context.InternalOffset = (ulong)(currentTimePoint.NanoSeconds - ticksTimeSpan.NanoSeconds); - - WriteObjectToSharedMemory(SteadyClockContextOffset, 4, context); - } - - public void UpdateLocalSystemClockContext(SystemClockContext context) - { - WriteObjectToSharedMemory(LocalSystemClockContextOffset, 4, context); - } - - public void UpdateNetworkSystemClockContext(SystemClockContext context) - { - WriteObjectToSharedMemory(NetworkSystemClockContextOffset, 4, context); - } - - private T ReadObjectFromSharedMemory<T>(ulong offset, ulong padding) where T : unmanaged - { - T result; - uint index; - uint possiblyNewIndex; - - do - { - index = _timeSharedMemoryStorage.GetRef<uint>(offset); - - ulong objectOffset = offset + 4 + padding + (ulong)((index & 1) * Unsafe.SizeOf<T>()); - - result = _timeSharedMemoryStorage.GetRef<T>(objectOffset); - - Thread.MemoryBarrier(); - - possiblyNewIndex = _device.Memory.Read<uint>(offset); - } while (index != possiblyNewIndex); - - return result; - } - - private void WriteObjectToSharedMemory<T>(ulong offset, ulong padding, T value) where T : unmanaged - { - uint newIndex = _timeSharedMemoryStorage.GetRef<uint>(offset) + 1; - - ulong objectOffset = offset + 4 + padding + (ulong)((newIndex & 1) * Unsafe.SizeOf<T>()); - - _timeSharedMemoryStorage.GetRef<T>(objectOffset) = value; - - Thread.MemoryBarrier(); - - _timeSharedMemoryStorage.GetRef<uint>(offset) = newIndex; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs deleted file mode 100644 index f7477e97..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZone.cs +++ /dev/null @@ -1,1703 +0,0 @@ -using Ryujinx.Common; -using Ryujinx.Common.Memory; -using Ryujinx.Common.Utilities; -using Ryujinx.HLE.Utilities; -using System; -using System.Buffers.Binary; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -using static Ryujinx.HLE.HOS.Services.Time.TimeZone.TimeZoneRule; - -namespace Ryujinx.HLE.HOS.Services.Time.TimeZone -{ - public class TimeZone - { - private const int TimeTypeSize = 8; - private const int EpochYear = 1970; - private const int YearBase = 1900; - private const int EpochWeekDay = 4; - private const int SecondsPerMinute = 60; - private const int MinutesPerHour = 60; - private const int HoursPerDays = 24; - private const int DaysPerWekk = 7; - private const int DaysPerNYear = 365; - private const int DaysPerLYear = 366; - private const int MonthsPerYear = 12; - private const int SecondsPerHour = SecondsPerMinute * MinutesPerHour; - private const int SecondsPerDay = SecondsPerHour * HoursPerDays; - - private const int YearsPerRepeat = 400; - private const long AverageSecondsPerYear = 31556952; - private const long SecondsPerRepeat = YearsPerRepeat * AverageSecondsPerYear; - - private static readonly int[] YearLengths = { DaysPerNYear, DaysPerLYear }; - private static readonly int[][] MonthsLengths = new int[][] - { - new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - new int[] { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } - }; - - private static ReadOnlySpan<byte> TimeZoneDefaultRule => ",M4.1.0,M10.5.0"u8; - - [StructLayout(LayoutKind.Sequential, Pack = 0x4, Size = 0x10)] - private struct CalendarTimeInternal - { - // NOTE: On the IPC side this is supposed to be a 16 bits value but internally this need to be a 64 bits value for ToPosixTime. - public long Year; - public sbyte Month; - public sbyte Day; - public sbyte Hour; - public sbyte Minute; - public sbyte Second; - - public int CompareTo(CalendarTimeInternal other) - { - if (Year != other.Year) - { - if (Year < other.Year) - { - return -1; - } - - return 1; - } - - if (Month != other.Month) - { - return Month - other.Month; - } - - if (Day != other.Day) - { - return Day - other.Day; - } - - if (Hour != other.Hour) - { - return Hour - other.Hour; - } - - if (Minute != other.Minute) - { - return Minute - other.Minute; - } - - if (Second != other.Second) - { - return Second - other.Second; - } - - return 0; - } - } - - private enum RuleType - { - JulianDay, - DayOfYear, - MonthNthDayOfWeek - } - - private struct Rule - { - public RuleType Type; - public int Day; - public int Week; - public int Month; - public int TransitionTime; - } - - private static int Detzcode32(ReadOnlySpan<byte> bytes) - { - return BinaryPrimitives.ReadInt32BigEndian(bytes); - } - - private static int Detzcode32(int value) - { - if (BitConverter.IsLittleEndian) - { - return BinaryPrimitives.ReverseEndianness(value); - } - - return value; - } - - private static long Detzcode64(ReadOnlySpan<byte> bytes) - { - return BinaryPrimitives.ReadInt64BigEndian(bytes); - } - - private static bool DifferByRepeat(long t1, long t0) - { - return (t1 - t0) == SecondsPerRepeat; - } - - private static bool TimeTypeEquals(in TimeZoneRule outRules, byte aIndex, byte bIndex) - { - if (aIndex < 0 || aIndex >= outRules.TypeCount || bIndex < 0 || bIndex >= outRules.TypeCount) - { - return false; - } - - TimeTypeInfo a = outRules.Ttis[aIndex]; - TimeTypeInfo b = outRules.Ttis[bIndex]; - - return a.GmtOffset == b.GmtOffset && - a.IsDaySavingTime == b.IsDaySavingTime && - a.IsStandardTimeDaylight == b.IsStandardTimeDaylight && - a.IsGMT == b.IsGMT && - StringUtils.CompareCStr(outRules.Chars[a.AbbreviationListIndex..], outRules.Chars[b.AbbreviationListIndex..]) == 0; - } - - private static int GetQZName(ReadOnlySpan<byte> name, int namePosition, char delimiter) - { - int i = namePosition; - - while (name[i] != '\0' && name[i] != delimiter) - { - i++; - } - - return i; - } - - private static int GetTZName(ReadOnlySpan<byte> name, int namePosition) - { - int i = namePosition; - - char c; - - while ((c = (char)name[i]) != '\0' && !char.IsDigit(c) && c != ',' && c != '-' && c != '+') - { - i++; - } - - return i; - } - - private static bool GetNum(ReadOnlySpan<byte> name, ref int namePosition, out int num, int min, int max) - { - num = 0; - - if (namePosition >= name.Length) - { - return false; - } - - char c = (char)name[namePosition]; - - if (!char.IsDigit(c)) - { - return false; - } - - do - { - num = num * 10 + (c - '0'); - if (num > max) - { - return false; - } - - if (++namePosition >= name.Length) - { - return false; - } - - c = (char)name[namePosition]; - } - while (char.IsDigit(c)); - - if (num < min) - { - return false; - } - - return true; - } - - private static bool GetSeconds(ReadOnlySpan<byte> name, ref int namePosition, out int seconds) - { - seconds = 0; - - - bool isValid = GetNum(name, ref namePosition, out int num, 0, HoursPerDays * DaysPerWekk - 1); - if (!isValid) - { - return false; - } - - seconds = num * SecondsPerHour; - - if (namePosition >= name.Length) - { - return false; - } - - if (name[namePosition] == ':') - { - namePosition++; - isValid = GetNum(name, ref namePosition, out num, 0, MinutesPerHour - 1); - if (!isValid) - { - return false; - } - - seconds += num * SecondsPerMinute; - - if (namePosition >= name.Length) - { - return false; - } - - if (name[namePosition] == ':') - { - namePosition++; - isValid = GetNum(name, ref namePosition, out num, 0, SecondsPerMinute); - if (!isValid) - { - return false; - } - - seconds += num; - } - } - return true; - } - - private static bool GetOffset(ReadOnlySpan<byte> name, ref int namePosition, ref int offset) - { - bool isNegative = false; - - if (namePosition >= name.Length) - { - return false; - } - - if (name[namePosition] == '-') - { - isNegative = true; - namePosition++; - } - else if (name[namePosition] == '+') - { - namePosition++; - } - - if (namePosition >= name.Length) - { - return false; - } - - bool isValid = GetSeconds(name, ref namePosition, out offset); - if (!isValid) - { - return false; - } - - if (isNegative) - { - offset = -offset; - } - - return true; - } - - private static bool GetRule(ReadOnlySpan<byte> name, ref int namePosition, out Rule rule) - { - rule = new Rule(); - - bool isValid = false; - - if (name[namePosition] == 'J') - { - namePosition++; - - rule.Type = RuleType.JulianDay; - isValid = GetNum(name, ref namePosition, out rule.Day, 1, DaysPerNYear); - } - else if (name[namePosition] == 'M') - { - namePosition++; - - rule.Type = RuleType.MonthNthDayOfWeek; - isValid = GetNum(name, ref namePosition, out rule.Month, 1, MonthsPerYear); - - if (!isValid) - { - return false; - } - - if (name[namePosition++] != '.') - { - return false; - } - - isValid = GetNum(name, ref namePosition, out rule.Week, 1, 5); - if (!isValid) - { - return false; - } - - if (name[namePosition++] != '.') - { - return false; - } - - isValid = GetNum(name, ref namePosition, out rule.Day, 0, DaysPerWekk - 1); - } - else if (char.IsDigit((char)name[namePosition])) - { - rule.Type = RuleType.DayOfYear; - isValid = GetNum(name, ref namePosition, out rule.Day, 0, DaysPerLYear - 1); - } - else - { - return false; - } - - if (!isValid) - { - return false; - } - - if (name[namePosition] == '/') - { - namePosition++; - return GetOffset(name, ref namePosition, ref rule.TransitionTime); - } - else - { - rule.TransitionTime = 2 * SecondsPerHour; - } - - return true; - } - - private static int IsLeap(int year) - { - if (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0)) - { - return 1; - } - - return 0; - } - - private static bool ParsePosixName(ReadOnlySpan<byte> name, ref TimeZoneRule outRules, bool lastDitch) - { - outRules = new TimeZoneRule(); - - int stdLen; - - ReadOnlySpan<byte> stdName = name; - int namePosition = 0; - int stdOffset = 0; - - if (lastDitch) - { - stdLen = 3; - namePosition += stdLen; - } - else - { - if (name[namePosition] == '<') - { - namePosition++; - - stdName = name.Slice(namePosition); - - int stdNamePosition = namePosition; - - namePosition = GetQZName(name, namePosition, '>'); - - if (name[namePosition] != '>') - { - return false; - } - - stdLen = namePosition - stdNamePosition; - namePosition++; - } - else - { - namePosition = GetTZName(name, namePosition); - stdLen = namePosition; - } - - if (stdLen == 0) - { - return false; - } - - bool isValid = GetOffset(name.ToArray(), ref namePosition, ref stdOffset); - - if (!isValid) - { - return false; - } - } - - int charCount = stdLen + 1; - int destLen = 0; - int dstOffset = 0; - - ReadOnlySpan<byte> destName = name.Slice(namePosition); - - if (TzCharsArraySize < charCount) - { - return false; - } - - if (name[namePosition] != '\0') - { - if (name[namePosition] == '<') - { - destName = name.Slice(++namePosition); - int destNamePosition = namePosition; - - namePosition = GetQZName(name.ToArray(), namePosition, '>'); - - if (name[namePosition] != '>') - { - return false; - } - - destLen = namePosition - destNamePosition; - namePosition++; - } - else - { - destName = name.Slice(namePosition); - namePosition = GetTZName(name, namePosition); - destLen = namePosition; - } - - if (destLen == 0) - { - return false; - } - - charCount += destLen + 1; - if (TzCharsArraySize < charCount) - { - return false; - } - - if (name[namePosition] != '\0' && name[namePosition] != ',' && name[namePosition] != ';') - { - bool isValid = GetOffset(name.ToArray(), ref namePosition, ref dstOffset); - - if (!isValid) - { - return false; - } - } - else - { - dstOffset = stdOffset - SecondsPerHour; - } - - if (name[namePosition] == '\0') - { - name = TimeZoneDefaultRule; - namePosition = 0; - } - - if (name[namePosition] == ',' || name[namePosition] == ';') - { - namePosition++; - - bool IsRuleValid = GetRule(name, ref namePosition, out Rule start); - if (!IsRuleValid) - { - return false; - } - - if (name[namePosition++] != ',') - { - return false; - } - - IsRuleValid = GetRule(name, ref namePosition, out Rule end); - if (!IsRuleValid) - { - return false; - } - - if (name[namePosition] != '\0') - { - return false; - } - - outRules.TypeCount = 2; - - outRules.Ttis[0] = new TimeTypeInfo - { - GmtOffset = -dstOffset, - IsDaySavingTime = true, - AbbreviationListIndex = stdLen + 1 - }; - - outRules.Ttis[1] = new TimeTypeInfo - { - GmtOffset = -stdOffset, - IsDaySavingTime = false, - AbbreviationListIndex = 0 - }; - - outRules.DefaultType = 0; - - int timeCount = 0; - long janFirst = 0; - int janOffset = 0; - int yearBegining = EpochYear; - - do - { - int yearSeconds = YearLengths[IsLeap(yearBegining - 1)] * SecondsPerDay; - yearBegining--; - if (IncrementOverflow64(ref janFirst, -yearSeconds)) - { - janOffset = -yearSeconds; - break; - } - } - while (EpochYear - YearsPerRepeat / 2 < yearBegining); - - int yearLimit = yearBegining + YearsPerRepeat + 1; - int year; - for (year = yearBegining; year < yearLimit; year++) - { - int startTime = TransitionTime(year, start, stdOffset); - int endTime = TransitionTime(year, end, dstOffset); - - int yearSeconds = YearLengths[IsLeap(year)] * SecondsPerDay; - - bool isReversed = endTime < startTime; - if (isReversed) - { - int swap = startTime; - - startTime = endTime; - endTime = swap; - } - - if (isReversed || (startTime < endTime && (endTime - startTime < (yearSeconds + (stdOffset - dstOffset))))) - { - if (TzMaxTimes - 2 < timeCount) - { - break; - } - - outRules.Ats[timeCount] = janFirst; - if (!IncrementOverflow64(ref outRules.Ats[timeCount], janOffset + startTime)) - { - outRules.Types[timeCount++] = isReversed ? (byte)1 : (byte)0; - } - else if (janOffset != 0) - { - outRules.DefaultType = isReversed ? 1 : 0; - } - - outRules.Ats[timeCount] = janFirst; - if (!IncrementOverflow64(ref outRules.Ats[timeCount], janOffset + endTime)) - { - outRules.Types[timeCount++] = isReversed ? (byte)0 : (byte)1; - yearLimit = year + YearsPerRepeat + 1; - } - else if (janOffset != 0) - { - outRules.DefaultType = isReversed ? 0 : 1; - } - } - - if (IncrementOverflow64(ref janFirst, janOffset + yearSeconds)) - { - break; - } - - janOffset = 0; - } - - outRules.TimeCount = timeCount; - - // There is no time variation, this is then a perpetual DST rule - if (timeCount == 0) - { - outRules.TypeCount = 1; - } - else if (YearsPerRepeat < year - yearBegining) - { - outRules.GoBack = true; - outRules.GoAhead = true; - } - } - else - { - if (name[namePosition] == '\0') - { - return false; - } - - long theirStdOffset = 0; - for (int i = 0; i < outRules.TimeCount; i++) - { - int j = outRules.Types[i]; - if (outRules.Ttis[j].IsStandardTimeDaylight) - { - theirStdOffset = -outRules.Ttis[j].GmtOffset; - } - } - - long theirDstOffset = 0; - for (int i = 0; i < outRules.TimeCount; i++) - { - int j = outRules.Types[i]; - if (outRules.Ttis[j].IsDaySavingTime) - { - theirDstOffset = -outRules.Ttis[j].GmtOffset; - } - } - - bool isDaySavingTime = false; - long theirOffset = theirStdOffset; - for (int i = 0; i < outRules.TimeCount; i++) - { - int j = outRules.Types[i]; - outRules.Types[i] = outRules.Ttis[j].IsDaySavingTime ? (byte)1 : (byte)0; - if (!outRules.Ttis[j].IsGMT) - { - if (isDaySavingTime && !outRules.Ttis[j].IsStandardTimeDaylight) - { - outRules.Ats[i] += dstOffset - theirStdOffset; - } - else - { - outRules.Ats[i] += stdOffset - theirStdOffset; - } - } - - theirOffset = -outRules.Ttis[j].GmtOffset; - if (outRules.Ttis[j].IsDaySavingTime) - { - theirDstOffset = theirOffset; - } - else - { - theirStdOffset = theirOffset; - } - } - - outRules.Ttis[0] = new TimeTypeInfo - { - GmtOffset = -stdOffset, - IsDaySavingTime = false, - AbbreviationListIndex = 0 - }; - - outRules.Ttis[1] = new TimeTypeInfo - { - GmtOffset = -dstOffset, - IsDaySavingTime = true, - AbbreviationListIndex = stdLen + 1 - }; - - outRules.TypeCount = 2; - outRules.DefaultType = 0; - } - } - else - { - // default is perpetual standard time - outRules.TypeCount = 1; - outRules.TimeCount = 0; - outRules.DefaultType = 0; - outRules.Ttis[0] = new TimeTypeInfo - { - GmtOffset = -stdOffset, - IsDaySavingTime = false, - AbbreviationListIndex = 0 - }; - } - - outRules.CharCount = charCount; - - int charsPosition = 0; - - for (int i = 0; i < stdLen; i++) - { - outRules.Chars[i] = stdName[i]; - } - - charsPosition += stdLen; - outRules.Chars[charsPosition++] = 0; - - if (destLen != 0) - { - for (int i = 0; i < destLen; i++) - { - outRules.Chars[charsPosition + i] = destName[i]; - } - outRules.Chars[charsPosition + destLen] = 0; - } - - return true; - } - - private static int TransitionTime(int year, Rule rule, int offset) - { - int leapYear = IsLeap(year); - - int value; - switch (rule.Type) - { - case RuleType.JulianDay: - value = (rule.Day - 1) * SecondsPerDay; - if (leapYear == 1 && rule.Day >= 60) - { - value += SecondsPerDay; - } - break; - - case RuleType.DayOfYear: - value = rule.Day * SecondsPerDay; - break; - - case RuleType.MonthNthDayOfWeek: - // Here we use Zeller's Congruence to get the day of week of the first month. - - int m1 = (rule.Month + 9) % 12 + 1; - int yy0 = (rule.Month <= 2) ? (year - 1) : year; - int yy1 = yy0 / 100; - int yy2 = yy0 % 100; - - int dayOfWeek = ((26 * m1 - 2) / 10 + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; - - if (dayOfWeek < 0) - { - dayOfWeek += DaysPerWekk; - } - - // Get the zero origin - int d = rule.Day - dayOfWeek; - - if (d < 0) - { - d += DaysPerWekk; - } - - for (int i = 1; i < rule.Week; i++) - { - if (d + DaysPerWekk >= MonthsLengths[leapYear][rule.Month - 1]) - { - break; - } - - d += DaysPerWekk; - } - - value = d * SecondsPerDay; - for (int i = 0; i < rule.Month - 1; i++) - { - value += MonthsLengths[leapYear][i] * SecondsPerDay; - } - - break; - default: - throw new NotImplementedException("Unknown time transition!"); - } - - return value + rule.TransitionTime + offset; - } - - private static bool NormalizeOverflow32(ref int ip, ref int unit, int baseValue) - { - int delta; - - if (unit >= 0) - { - delta = unit / baseValue; - } - else - { - delta = -1 - (-1 - unit) / baseValue; - } - - unit -= delta * baseValue; - - return IncrementOverflow32(ref ip, delta); - } - - private static bool NormalizeOverflow64(ref long ip, ref long unit, long baseValue) - { - long delta; - - if (unit >= 0) - { - delta = unit / baseValue; - } - else - { - delta = -1 - (-1 - unit) / baseValue; - } - - unit -= delta * baseValue; - - return IncrementOverflow64(ref ip, delta); - } - - private static bool IncrementOverflow32(ref int time, int j) - { - try - { - time = checked(time + j); - - return false; - } - catch (OverflowException) - { - return true; - } - } - - private static bool IncrementOverflow64(ref long time, long j) - { - try - { - time = checked(time + j); - - return false; - } - catch (OverflowException) - { - return true; - } - } - - internal static bool ParsePosixName(string name, ref TimeZoneRule outRules) - { - return ParsePosixName(Encoding.ASCII.GetBytes(name), ref outRules, false); - } - - internal static bool ParseTimeZoneBinary(ref TimeZoneRule outRules, Stream inputData) - { - outRules = new TimeZoneRule(); - - BinaryReader reader = new BinaryReader(inputData); - - long streamLength = reader.BaseStream.Length; - - if (streamLength < Unsafe.SizeOf<TzifHeader>()) - { - return false; - } - - TzifHeader header = reader.ReadStruct<TzifHeader>(); - - streamLength -= Unsafe.SizeOf<TzifHeader>(); - - int ttisGMTCount = Detzcode32(header.TtisGMTCount); - int ttisSTDCount = Detzcode32(header.TtisSTDCount); - int leapCount = Detzcode32(header.LeapCount); - int timeCount = Detzcode32(header.TimeCount); - int typeCount = Detzcode32(header.TypeCount); - int charCount = Detzcode32(header.CharCount); - - if (!(0 <= leapCount - && leapCount < TzMaxLeaps - && 0 < typeCount - && typeCount < TzMaxTypes - && 0 <= timeCount - && timeCount < TzMaxTimes - && 0 <= charCount - && charCount < TzMaxChars - && (ttisSTDCount == typeCount || ttisSTDCount == 0) - && (ttisGMTCount == typeCount || ttisGMTCount == 0))) - { - return false; - } - - - if (streamLength < (timeCount * TimeTypeSize - + timeCount - + typeCount * 6 - + charCount - + leapCount * (TimeTypeSize + 4) - + ttisSTDCount - + ttisGMTCount)) - { - return false; - } - - outRules.TimeCount = timeCount; - outRules.TypeCount = typeCount; - outRules.CharCount = charCount; - - byte[] workBuffer = StreamUtils.StreamToBytes(inputData); - - timeCount = 0; - - { - Span<byte> p = workBuffer; - for (int i = 0; i < outRules.TimeCount; i++) - { - long at = Detzcode64(p); - outRules.Types[i] = 1; - - if (timeCount != 0 && at <= outRules.Ats[timeCount - 1]) - { - if (at < outRules.Ats[timeCount - 1]) - { - return false; - } - - outRules.Types[i - 1] = 0; - timeCount--; - } - - outRules.Ats[timeCount++] = at; - - p = p[TimeTypeSize..]; - } - - timeCount = 0; - for (int i = 0; i < outRules.TimeCount; i++) - { - byte type = p[0]; - p = p[1..]; - - if (outRules.TypeCount <= type) - { - return false; - } - - if (outRules.Types[i] != 0) - { - outRules.Types[timeCount++] = type; - } - } - - outRules.TimeCount = timeCount; - - for (int i = 0; i < outRules.TypeCount; i++) - { - TimeTypeInfo ttis = outRules.Ttis[i]; - ttis.GmtOffset = Detzcode32(p); - p = p[sizeof(int)..]; - - if (p[0] >= 2) - { - return false; - } - - ttis.IsDaySavingTime = p[0] != 0; - p = p[1..]; - - int abbreviationListIndex = p[0]; - p = p[1..]; - - if (abbreviationListIndex >= outRules.CharCount) - { - return false; - } - - ttis.AbbreviationListIndex = abbreviationListIndex; - - outRules.Ttis[i] = ttis; - } - - p[..outRules.CharCount].CopyTo(outRules.Chars); - - p = p[outRules.CharCount..]; - outRules.Chars[outRules.CharCount] = 0; - - for (int i = 0; i < outRules.TypeCount; i++) - { - if (ttisSTDCount == 0) - { - outRules.Ttis[i].IsStandardTimeDaylight = false; - } - else - { - if (p[0] >= 2) - { - return false; - } - - outRules.Ttis[i].IsStandardTimeDaylight = p[0] != 0; - p = p[1..]; - } - } - - for (int i = 0; i < outRules.TypeCount; i++) - { - if (ttisSTDCount == 0) - { - outRules.Ttis[i].IsGMT = false; - } - else - { - if (p[0] >= 2) - { - return false; - } - - outRules.Ttis[i].IsGMT = p[0] != 0; - p = p[1..]; - } - - } - - long position = (workBuffer.Length - p.Length); - long nRead = streamLength - position; - - if (nRead < 0) - { - return false; - } - - // Nintendo abort in case of a TzIf file with a POSIX TZ Name too long to fit inside a TimeZoneRule. - // As it's impossible in normal usage to achive this, we also force a crash. - if (nRead > (TzNameMax + 1)) - { - throw new InvalidOperationException(); - } - - byte[] tempName = new byte[TzNameMax + 1]; - Array.Copy(workBuffer, position, tempName, 0, nRead); - - if (nRead > 2 && tempName[0] == '\n' && tempName[nRead - 1] == '\n' && outRules.TypeCount + 2 <= TzMaxTypes) - { - tempName[nRead - 1] = 0; - - byte[] name = new byte[TzNameMax]; - Array.Copy(tempName, 1, name, 0, nRead - 1); - - Box<TimeZoneRule> tempRulesBox = new Box<TimeZoneRule>(); - ref TimeZoneRule tempRules = ref tempRulesBox.Data; - - if (ParsePosixName(name, ref tempRulesBox.Data, false)) - { - int abbreviationCount = 0; - charCount = outRules.CharCount; - - Span<byte> chars = outRules.Chars; - - for (int i = 0; i < tempRules.TypeCount; i++) - { - ReadOnlySpan<byte> tempChars = tempRules.Chars; - ReadOnlySpan<byte> tempAbbreviation = tempChars[tempRules.Ttis[i].AbbreviationListIndex..]; - - int j; - - for (j = 0; j < charCount; j++) - { - if (StringUtils.CompareCStr(chars[j..], tempAbbreviation) == 0) - { - tempRules.Ttis[i].AbbreviationListIndex = j; - abbreviationCount++; - break; - } - } - - if (j >= charCount) - { - int abbreviationLength = StringUtils.LengthCstr(tempAbbreviation); - if (j + abbreviationLength < TzMaxChars) - { - for (int x = 0; x < abbreviationLength; x++) - { - chars[j + x] = tempAbbreviation[x]; - } - - charCount = j + abbreviationLength + 1; - - tempRules.Ttis[i].AbbreviationListIndex = j; - abbreviationCount++; - } - } - } - - if (abbreviationCount == tempRules.TypeCount) - { - outRules.CharCount = charCount; - - // Remove trailing - while (1 < outRules.TimeCount && (outRules.Types[outRules.TimeCount - 1] == outRules.Types[outRules.TimeCount - 2])) - { - outRules.TimeCount--; - } - - int i; - - for (i = 0; i < tempRules.TimeCount; i++) - { - if (outRules.TimeCount == 0 || outRules.Ats[outRules.TimeCount - 1] < tempRules.Ats[i]) - { - break; - } - } - - while (i < tempRules.TimeCount && outRules.TimeCount < TzMaxTimes) - { - outRules.Ats[outRules.TimeCount] = tempRules.Ats[i]; - outRules.Types[outRules.TimeCount] = (byte)(outRules.TypeCount + (byte)tempRules.Types[i]); - - outRules.TimeCount++; - i++; - } - - for (i = 0; i < tempRules.TypeCount; i++) - { - outRules.Ttis[outRules.TypeCount++] = tempRules.Ttis[i]; - } - } - } - } - - if (outRules.TypeCount == 0) - { - return false; - } - - if (outRules.TimeCount > 1) - { - for (int i = 1; i < outRules.TimeCount; i++) - { - if (TimeTypeEquals(in outRules, outRules.Types[i], outRules.Types[0]) && DifferByRepeat(outRules.Ats[i], outRules.Ats[0])) - { - outRules.GoBack = true; - break; - } - } - - for (int i = outRules.TimeCount - 2; i >= 0; i--) - { - if (TimeTypeEquals(in outRules, outRules.Types[outRules.TimeCount - 1], outRules.Types[i]) && DifferByRepeat(outRules.Ats[outRules.TimeCount - 1], outRules.Ats[i])) - { - outRules.GoAhead = true; - break; - } - } - } - - int defaultType; - - for (defaultType = 0; defaultType < outRules.TimeCount; defaultType++) - { - if (outRules.Types[defaultType] == 0) - { - break; - } - } - - defaultType = defaultType < outRules.TimeCount ? -1 : 0; - - if (defaultType < 0 && outRules.TimeCount > 0 && outRules.Ttis[outRules.Types[0]].IsDaySavingTime) - { - defaultType = outRules.Types[0]; - while (--defaultType >= 0) - { - if (!outRules.Ttis[defaultType].IsDaySavingTime) - { - break; - } - } - } - - if (defaultType < 0) - { - defaultType = 0; - while (outRules.Ttis[defaultType].IsDaySavingTime) - { - if (++defaultType >= outRules.TypeCount) - { - defaultType = 0; - break; - } - } - } - - outRules.DefaultType = defaultType; - } - - return true; - } - - private static long GetLeapDaysNotNeg(long year) - { - return year / 4 - year / 100 + year / 400; - } - - private static long GetLeapDays(long year) - { - if (year < 0) - { - return -1 - GetLeapDaysNotNeg(-1 - year); - } - else - { - return GetLeapDaysNotNeg(year); - } - } - - private static ResultCode CreateCalendarTime(long time, int gmtOffset, out CalendarTimeInternal calendarTime, out CalendarAdditionalInfo calendarAdditionalInfo) - { - long year = EpochYear; - long timeDays = time / SecondsPerDay; - long remainingSeconds = time % SecondsPerDay; - - calendarTime = new CalendarTimeInternal(); - calendarAdditionalInfo = new CalendarAdditionalInfo(); - - while (timeDays < 0 || timeDays >= YearLengths[IsLeap((int)year)]) - { - long timeDelta = timeDays / DaysPerLYear; - long delta = timeDelta; - - if (delta == 0) - { - delta = timeDays < 0 ? -1 : 1; - } - - long newYear = year; - - if (IncrementOverflow64(ref newYear, delta)) - { - return ResultCode.OutOfRange; - } - - long leapDays = GetLeapDays(newYear - 1) - GetLeapDays(year - 1); - timeDays -= (newYear - year) * DaysPerNYear; - timeDays -= leapDays; - year = newYear; - } - - long dayOfYear = timeDays; - remainingSeconds += gmtOffset; - while (remainingSeconds < 0) - { - remainingSeconds += SecondsPerDay; - dayOfYear -= 1; - } - - while (remainingSeconds >= SecondsPerDay) - { - remainingSeconds -= SecondsPerDay; - dayOfYear += 1; - } - - while (dayOfYear < 0) - { - if (IncrementOverflow64(ref year, -1)) - { - return ResultCode.OutOfRange; - } - - dayOfYear += YearLengths[IsLeap((int)year)]; - } - - while (dayOfYear >= YearLengths[IsLeap((int)year)]) - { - dayOfYear -= YearLengths[IsLeap((int)year)]; - - if (IncrementOverflow64(ref year, 1)) - { - return ResultCode.OutOfRange; - } - } - - calendarTime.Year = year; - calendarAdditionalInfo.DayOfYear = (uint)dayOfYear; - - long dayOfWeek = (EpochWeekDay + ((year - EpochYear) % DaysPerWekk) * (DaysPerNYear % DaysPerWekk) + GetLeapDays(year - 1) - GetLeapDays(EpochYear - 1) + dayOfYear) % DaysPerWekk; - if (dayOfWeek < 0) - { - dayOfWeek += DaysPerWekk; - } - - calendarAdditionalInfo.DayOfWeek = (uint)dayOfWeek; - - calendarTime.Hour = (sbyte)((remainingSeconds / SecondsPerHour) % SecondsPerHour); - remainingSeconds %= SecondsPerHour; - - calendarTime.Minute = (sbyte)(remainingSeconds / SecondsPerMinute); - calendarTime.Second = (sbyte)(remainingSeconds % SecondsPerMinute); - - int[] ip = MonthsLengths[IsLeap((int)year)]; - - for (calendarTime.Month = 0; dayOfYear >= ip[calendarTime.Month]; ++calendarTime.Month) - { - dayOfYear -= ip[calendarTime.Month]; - } - - calendarTime.Day = (sbyte)(dayOfYear + 1); - - calendarAdditionalInfo.IsDaySavingTime = false; - calendarAdditionalInfo.GmtOffset = gmtOffset; - - return 0; - } - - private static ResultCode ToCalendarTimeInternal(in TimeZoneRule rules, long time, out CalendarTimeInternal calendarTime, out CalendarAdditionalInfo calendarAdditionalInfo) - { - calendarTime = new CalendarTimeInternal(); - calendarAdditionalInfo = new CalendarAdditionalInfo(); - - ResultCode result; - - if ((rules.GoAhead && time < rules.Ats[0]) || (rules.GoBack && time > rules.Ats[rules.TimeCount - 1])) - { - long newTime = time; - - long seconds; - long years; - - if (time < rules.Ats[0]) - { - seconds = rules.Ats[0] - time; - } - else - { - seconds = time - rules.Ats[rules.TimeCount - 1]; - } - - seconds -= 1; - - years = (seconds / SecondsPerRepeat + 1) * YearsPerRepeat; - seconds = years * AverageSecondsPerYear; - - if (time < rules.Ats[0]) - { - newTime += seconds; - } - else - { - newTime -= seconds; - } - - if (newTime < rules.Ats[0] && newTime > rules.Ats[rules.TimeCount - 1]) - { - return ResultCode.TimeNotFound; - } - - result = ToCalendarTimeInternal(in rules, newTime, out calendarTime, out calendarAdditionalInfo); - if (result != 0) - { - return result; - } - - if (time < rules.Ats[0]) - { - calendarTime.Year -= years; - } - else - { - calendarTime.Year += years; - } - - return ResultCode.Success; - } - - int ttiIndex; - - if (rules.TimeCount == 0 || time < rules.Ats[0]) - { - ttiIndex = rules.DefaultType; - } - else - { - int low = 1; - int high = rules.TimeCount; - - while (low < high) - { - int mid = (low + high) >> 1; - - if (time < rules.Ats[mid]) - { - high = mid; - } - else - { - low = mid + 1; - } - } - - ttiIndex = rules.Types[low - 1]; - } - - result = CreateCalendarTime(time, rules.Ttis[ttiIndex].GmtOffset, out calendarTime, out calendarAdditionalInfo); - - if (result == 0) - { - calendarAdditionalInfo.IsDaySavingTime = rules.Ttis[ttiIndex].IsDaySavingTime; - - ReadOnlySpan<byte> timeZoneAbbreviation = rules.Chars[rules.Ttis[ttiIndex].AbbreviationListIndex..]; - - int timeZoneSize = Math.Min(StringUtils.LengthCstr(timeZoneAbbreviation), 8); - - timeZoneAbbreviation[..timeZoneSize].CopyTo(calendarAdditionalInfo.TimezoneName.AsSpan()); - } - - return result; - } - - private static ResultCode ToPosixTimeInternal(in TimeZoneRule rules, CalendarTimeInternal calendarTime, out long posixTime) - { - posixTime = 0; - - int hour = calendarTime.Hour; - int minute = calendarTime.Minute; - - if (NormalizeOverflow32(ref hour, ref minute, MinutesPerHour)) - { - return ResultCode.Overflow; - } - - calendarTime.Minute = (sbyte)minute; - - int day = calendarTime.Day; - if (NormalizeOverflow32(ref day, ref hour, HoursPerDays)) - { - return ResultCode.Overflow; - } - - calendarTime.Day = (sbyte)day; - calendarTime.Hour = (sbyte)hour; - - long year = calendarTime.Year; - long month = calendarTime.Month; - - if (NormalizeOverflow64(ref year, ref month, MonthsPerYear)) - { - return ResultCode.Overflow; - } - - calendarTime.Month = (sbyte)month; - - if (IncrementOverflow64(ref year, YearBase)) - { - return ResultCode.Overflow; - } - - while (day <= 0) - { - if (IncrementOverflow64(ref year, -1)) - { - return ResultCode.Overflow; - } - - long li = year; - - if (1 < calendarTime.Month) - { - li++; - } - - day += YearLengths[IsLeap((int)li)]; - } - - while (day > DaysPerLYear) - { - long li = year; - - if (1 < calendarTime.Month) - { - li++; - } - - day -= YearLengths[IsLeap((int)li)]; - - if (IncrementOverflow64(ref year, 1)) - { - return ResultCode.Overflow; - } - } - - while (true) - { - int i = MonthsLengths[IsLeap((int)year)][calendarTime.Month]; - - if (day <= i) - { - break; - } - - day -= i; - calendarTime.Month += 1; - - if (calendarTime.Month >= MonthsPerYear) - { - calendarTime.Month = 0; - if (IncrementOverflow64(ref year, 1)) - { - return ResultCode.Overflow; - } - } - } - - calendarTime.Day = (sbyte)day; - - if (IncrementOverflow64(ref year, -YearBase)) - { - return ResultCode.Overflow; - } - - calendarTime.Year = year; - - int savedSeconds; - - if (calendarTime.Second >= 0 && calendarTime.Second < SecondsPerMinute) - { - savedSeconds = 0; - } - else if (year + YearBase < EpochYear) - { - int second = calendarTime.Second; - if (IncrementOverflow32(ref second, 1 - SecondsPerMinute)) - { - return ResultCode.Overflow; - } - - savedSeconds = second; - calendarTime.Second = 1 - SecondsPerMinute; - } - else - { - savedSeconds = calendarTime.Second; - calendarTime.Second = 0; - } - - long low = long.MinValue; - long high = long.MaxValue; - - while (true) - { - long pivot = low / 2 + high / 2; - - if (pivot < low) - { - pivot = low; - } - else if (pivot > high) - { - pivot = high; - } - - int direction; - - ResultCode result = ToCalendarTimeInternal(in rules, pivot, out CalendarTimeInternal candidateCalendarTime, out _); - if (result != 0) - { - if (pivot > 0) - { - direction = 1; - } - else - { - direction = -1; - } - } - else - { - direction = candidateCalendarTime.CompareTo(calendarTime); - } - - if (direction == 0) - { - long timeResult = pivot + savedSeconds; - - if ((timeResult < pivot) != (savedSeconds < 0)) - { - return ResultCode.Overflow; - } - - posixTime = timeResult; - break; - } - else - { - if (pivot == low) - { - if (pivot == long.MaxValue) - { - return ResultCode.TimeNotFound; - } - - pivot += 1; - low += 1; - } - else if (pivot == high) - { - if (pivot == long.MinValue) - { - return ResultCode.TimeNotFound; - } - - pivot -= 1; - high -= 1; - } - - if (low > high) - { - return ResultCode.TimeNotFound; - } - - if (direction > 0) - { - high = pivot; - } - else - { - low = pivot; - } - } - } - - return ResultCode.Success; - } - - internal static ResultCode ToCalendarTime(in TimeZoneRule rules, long time, out CalendarInfo calendar) - { - ResultCode result = ToCalendarTimeInternal(in rules, time, out CalendarTimeInternal calendarTime, out CalendarAdditionalInfo calendarAdditionalInfo); - - calendar = new CalendarInfo() - { - Time = new CalendarTime() - { - Year = (short)calendarTime.Year, - // NOTE: Nintendo's month range is 1-12, internal range is 0-11. - Month = (sbyte)(calendarTime.Month + 1), - Day = calendarTime.Day, - Hour = calendarTime.Hour, - Minute = calendarTime.Minute, - Second = calendarTime.Second - }, - AdditionalInfo = calendarAdditionalInfo - }; - - return result; - } - - internal static ResultCode ToPosixTime(in TimeZoneRule rules, CalendarTime calendarTime, out long posixTime) - { - CalendarTimeInternal calendarTimeInternal = new CalendarTimeInternal() - { - Year = calendarTime.Year, - // NOTE: Nintendo's month range is 1-12, internal range is 0-11. - Month = (sbyte)(calendarTime.Month - 1), - Day = calendarTime.Day, - Hour = calendarTime.Hour, - Minute = calendarTime.Minute, - Second = calendarTime.Second - }; - - return ToPosixTimeInternal(in rules, calendarTimeInternal, out posixTime); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs deleted file mode 100644 index 9367024e..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs +++ /dev/null @@ -1,304 +0,0 @@ -using LibHac; -using LibHac.Common; -using LibHac.Fs; -using LibHac.Fs.Fsa; -using LibHac.FsSystem; -using LibHac.Ncm; -using LibHac.Tools.FsSystem; -using LibHac.Tools.FsSystem.NcaUtils; -using Ryujinx.Common.Logging; -using Ryujinx.Cpu; -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.HOS.Services.Time.Clock; -using Ryujinx.HLE.Utilities; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using TimeZoneRuleBox = Ryujinx.Common.Memory.Box<Ryujinx.HLE.HOS.Services.Time.TimeZone.TimeZoneRule>; - -namespace Ryujinx.HLE.HOS.Services.Time.TimeZone -{ - public class TimeZoneContentManager - { - private const long TimeZoneBinaryTitleId = 0x010000000000080E; - - private readonly string TimeZoneSystemTitleMissingErrorMessage = "TimeZoneBinary system title not found! TimeZone conversions will not work, provide the system archive to fix this error. (See https://github.com/Ryujinx/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide#initial-setup-continued---installation-of-firmware for more information)"; - - private VirtualFileSystem _virtualFileSystem; - private IntegrityCheckLevel _fsIntegrityCheckLevel; - private ContentManager _contentManager; - - public string[] LocationNameCache { get; private set; } - - internal TimeZoneManager Manager { get; private set; } - - public TimeZoneContentManager() - { - Manager = new TimeZoneManager(); - } - - public void InitializeInstance(VirtualFileSystem virtualFileSystem, ContentManager contentManager, IntegrityCheckLevel fsIntegrityCheckLevel) - { - _virtualFileSystem = virtualFileSystem; - _contentManager = contentManager; - _fsIntegrityCheckLevel = fsIntegrityCheckLevel; - - InitializeLocationNameCache(); - } - - public string SanityCheckDeviceLocationName(string locationName) - { - if (IsLocationNameValid(locationName)) - { - return locationName; - } - - Logger.Warning?.Print(LogClass.ServiceTime, $"Invalid device TimeZone {locationName}, switching back to UTC"); - - return "UTC"; - } - - internal void Initialize(TimeManager timeManager, Switch device) - { - InitializeInstance(device.FileSystem, device.System.ContentManager, device.System.FsIntegrityCheckLevel); - - ITickSource tickSource = device.System.TickSource; - - SteadyClockTimePoint timeZoneUpdatedTimePoint = timeManager.StandardSteadyClock.GetCurrentTimePoint(tickSource); - - string deviceLocationName = SanityCheckDeviceLocationName(device.Configuration.TimeZone); - - ResultCode result = GetTimeZoneBinary(deviceLocationName, out Stream timeZoneBinaryStream, out LocalStorage ncaFile); - - if (result == ResultCode.Success) - { - // TODO: Read TimeZoneVersion from sysarchive. - timeManager.SetupTimeZoneManager(deviceLocationName, timeZoneUpdatedTimePoint, (uint)LocationNameCache.Length, new UInt128(), timeZoneBinaryStream); - - ncaFile.Dispose(); - } - else - { - // In the case the user don't have the timezone system archive, we just mark the manager as initialized. - Manager.MarkInitialized(); - } - } - - private void InitializeLocationNameCache() - { - if (HasTimeZoneBinaryTitle()) - { - using (IStorage ncaFileStream = new LocalStorage(_virtualFileSystem.SwitchPathToSystemPath(GetTimeZoneBinaryTitleContentPath()), FileAccess.Read, FileMode.Open)) - { - Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFileStream); - IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _fsIntegrityCheckLevel); - - using var binaryListFile = new UniqueRef<IFile>(); - - romfs.OpenFile(ref binaryListFile.Ref, "/binaryList.txt".ToU8Span(), OpenMode.Read).ThrowIfFailure(); - - StreamReader reader = new StreamReader(binaryListFile.Get.AsStream()); - - List<string> locationNameList = new List<string>(); - - string locationName; - while ((locationName = reader.ReadLine()) != null) - { - locationNameList.Add(locationName); - } - - LocationNameCache = locationNameList.ToArray(); - } - } - else - { - LocationNameCache = new string[] { "UTC" }; - - Logger.Error?.Print(LogClass.ServiceTime, TimeZoneSystemTitleMissingErrorMessage); - } - } - - public IEnumerable<(int Offset, string Location, string Abbr)> ParseTzOffsets() - { - var tzBinaryContentPath = GetTimeZoneBinaryTitleContentPath(); - - if (string.IsNullOrEmpty(tzBinaryContentPath)) - { - return new[] { (0, "UTC", "UTC") }; - } - - List<(int Offset, string Location, string Abbr)> outList = new List<(int Offset, string Location, string Abbr)>(); - var now = DateTimeOffset.Now.ToUnixTimeSeconds(); - using (IStorage ncaStorage = new LocalStorage(_virtualFileSystem.SwitchPathToSystemPath(tzBinaryContentPath), FileAccess.Read, FileMode.Open)) - using (IFileSystem romfs = new Nca(_virtualFileSystem.KeySet, ncaStorage).OpenFileSystem(NcaSectionType.Data, _fsIntegrityCheckLevel)) - { - foreach (string locName in LocationNameCache) - { - if (locName.StartsWith("Etc")) - { - continue; - } - - using var tzif = new UniqueRef<IFile>(); - - if (romfs.OpenFile(ref tzif.Ref, $"/zoneinfo/{locName}".ToU8Span(), OpenMode.Read).IsFailure()) - { - Logger.Error?.Print(LogClass.ServiceTime, $"Error opening /zoneinfo/{locName}"); - continue; - } - - TimeZoneRuleBox tzRuleBox = new TimeZoneRuleBox(); - ref TimeZoneRule tzRule = ref tzRuleBox.Data; - - TimeZone.ParseTimeZoneBinary(ref tzRule, tzif.Get.AsStream()); - - - TimeTypeInfo ttInfo; - if (tzRule.TimeCount > 0) // Find the current transition period - { - int fin = 0; - for (int i = 0; i < tzRule.TimeCount; ++i) - { - if (tzRule.Ats[i] <= now) - { - fin = i; - } - } - ttInfo = tzRule.Ttis[tzRule.Types[fin]]; - } - else if (tzRule.TypeCount >= 1) // Otherwise, use the first offset in TTInfo - { - ttInfo = tzRule.Ttis[0]; - } - else - { - Logger.Error?.Print(LogClass.ServiceTime, $"Couldn't find UTC offset for zone {locName}"); - continue; - } - - var abbrStart = tzRule.Chars[ttInfo.AbbreviationListIndex..]; - int abbrEnd = abbrStart.IndexOf((byte)0); - - outList.Add((ttInfo.GmtOffset, locName, Encoding.UTF8.GetString(abbrStart[..abbrEnd]))); - } - } - - outList.Sort(); - - return outList; - } - - private bool IsLocationNameValid(string locationName) - { - foreach (string cachedLocationName in LocationNameCache) - { - if (cachedLocationName.Equals(locationName)) - { - return true; - } - } - - return false; - } - - public ResultCode SetDeviceLocationName(string locationName) - { - ResultCode result = GetTimeZoneBinary(locationName, out Stream timeZoneBinaryStream, out LocalStorage ncaFile); - - if (result == ResultCode.Success) - { - result = Manager.SetDeviceLocationNameWithTimeZoneRule(locationName, timeZoneBinaryStream); - - ncaFile.Dispose(); - } - - return result; - } - - public ResultCode LoadLocationNameList(uint index, out string[] outLocationNameArray, uint maxLength) - { - List<string> locationNameList = new List<string>(); - - for (int i = 0; i < LocationNameCache.Length && i < maxLength; i++) - { - if (i < index) - { - continue; - } - - string locationName = LocationNameCache[i]; - - // If the location name is too long, error out. - if (locationName.Length > 0x24) - { - outLocationNameArray = Array.Empty<string>(); - - return ResultCode.LocationNameTooLong; - } - - locationNameList.Add(locationName); - } - - outLocationNameArray = locationNameList.ToArray(); - - return ResultCode.Success; - } - - public string GetTimeZoneBinaryTitleContentPath() - { - return _contentManager.GetInstalledContentPath(TimeZoneBinaryTitleId, StorageId.BuiltInSystem, NcaContentType.Data); - } - - public bool HasTimeZoneBinaryTitle() - { - return !string.IsNullOrEmpty(GetTimeZoneBinaryTitleContentPath()); - } - - internal ResultCode GetTimeZoneBinary(string locationName, out Stream timeZoneBinaryStream, out LocalStorage ncaFile) - { - timeZoneBinaryStream = null; - ncaFile = null; - - if (!HasTimeZoneBinaryTitle() || !IsLocationNameValid(locationName)) - { - return ResultCode.TimeZoneNotFound; - } - - ncaFile = new LocalStorage(_virtualFileSystem.SwitchPathToSystemPath(GetTimeZoneBinaryTitleContentPath()), FileAccess.Read, FileMode.Open); - - Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile); - IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _fsIntegrityCheckLevel); - - using var timeZoneBinaryFile = new UniqueRef<IFile>(); - - Result result = romfs.OpenFile(ref timeZoneBinaryFile.Ref, $"/zoneinfo/{locationName}".ToU8Span(), OpenMode.Read); - - timeZoneBinaryStream = timeZoneBinaryFile.Release().AsStream(); - - return (ResultCode)result.Value; - } - - internal ResultCode LoadTimeZoneRule(ref TimeZoneRule rules, string locationName) - { - rules = default; - - if (!HasTimeZoneBinaryTitle()) - { - throw new InvalidSystemResourceException(TimeZoneSystemTitleMissingErrorMessage); - } - - ResultCode result = GetTimeZoneBinary(locationName, out Stream timeZoneBinaryStream, out LocalStorage ncaFile); - - if (result == ResultCode.Success) - { - result = Manager.ParseTimeZoneRuleBinary(ref rules, timeZoneBinaryStream); - - ncaFile.Dispose(); - } - - return result; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs deleted file mode 100644 index ef4b7b39..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs +++ /dev/null @@ -1,261 +0,0 @@ -using Ryujinx.Common.Memory; -using Ryujinx.HLE.HOS.Services.Time.Clock; -using System; -using System.IO; - -namespace Ryujinx.HLE.HOS.Services.Time.TimeZone -{ - class TimeZoneManager - { - private bool _isInitialized; - private Box<TimeZoneRule> _myRules; - private string _deviceLocationName; - private UInt128 _timeZoneRuleVersion; - private uint _totalLocationNameCount; - private SteadyClockTimePoint _timeZoneUpdateTimePoint; - private object _lock; - - public TimeZoneManager() - { - _isInitialized = false; - _deviceLocationName = "UTC"; - _timeZoneRuleVersion = new UInt128(); - _lock = new object(); - _myRules = new Box<TimeZoneRule>(); - - _timeZoneUpdateTimePoint = SteadyClockTimePoint.GetRandom(); - } - - public bool IsInitialized() - { - bool res; - - lock (_lock) - { - res = _isInitialized; - } - - return res; - } - - public void MarkInitialized() - { - lock (_lock) - { - _isInitialized = true; - } - } - - public ResultCode GetDeviceLocationName(out string deviceLocationName) - { - ResultCode result = ResultCode.UninitializedClock; - - deviceLocationName = null; - - lock (_lock) - { - if (_isInitialized) - { - deviceLocationName = _deviceLocationName; - result = ResultCode.Success; - } - } - - return result; - } - - public ResultCode SetDeviceLocationNameWithTimeZoneRule(string locationName, Stream timeZoneBinaryStream) - { - ResultCode result = ResultCode.TimeZoneConversionFailed; - - lock (_lock) - { - Box<TimeZoneRule> rules = new Box<TimeZoneRule>(); - - bool timeZoneConversionSuccess = TimeZone.ParseTimeZoneBinary(ref rules.Data, timeZoneBinaryStream); - - if (timeZoneConversionSuccess) - { - _deviceLocationName = locationName; - _myRules = rules; - result = ResultCode.Success; - } - } - - return result; - } - - public void SetTotalLocationNameCount(uint totalLocationNameCount) - { - lock (_lock) - { - _totalLocationNameCount = totalLocationNameCount; - } - } - - public ResultCode GetTotalLocationNameCount(out uint totalLocationNameCount) - { - ResultCode result = ResultCode.UninitializedClock; - - totalLocationNameCount = 0; - - lock (_lock) - { - if (_isInitialized) - { - totalLocationNameCount = _totalLocationNameCount; - result = ResultCode.Success; - } - } - - return result; - } - - public ResultCode SetUpdatedTime(SteadyClockTimePoint timeZoneUpdatedTimePoint, bool bypassUninitialized = false) - { - ResultCode result = ResultCode.UninitializedClock; - - lock (_lock) - { - if (_isInitialized || bypassUninitialized) - { - _timeZoneUpdateTimePoint = timeZoneUpdatedTimePoint; - result = ResultCode.Success; - } - } - - return result; - } - - public ResultCode GetUpdatedTime(out SteadyClockTimePoint timeZoneUpdatedTimePoint) - { - ResultCode result; - - lock (_lock) - { - if (_isInitialized) - { - timeZoneUpdatedTimePoint = _timeZoneUpdateTimePoint; - result = ResultCode.Success; - } - else - { - timeZoneUpdatedTimePoint = SteadyClockTimePoint.GetRandom(); - result = ResultCode.UninitializedClock; - } - } - - return result; - } - - public ResultCode ParseTimeZoneRuleBinary(ref TimeZoneRule outRules, Stream timeZoneBinaryStream) - { - ResultCode result = ResultCode.Success; - - lock (_lock) - { - bool timeZoneConversionSuccess = TimeZone.ParseTimeZoneBinary(ref outRules, timeZoneBinaryStream); - - if (!timeZoneConversionSuccess) - { - result = ResultCode.TimeZoneConversionFailed; - } - } - - return result; - } - - public void SetTimeZoneRuleVersion(UInt128 timeZoneRuleVersion) - { - lock (_lock) - { - _timeZoneRuleVersion = timeZoneRuleVersion; - } - } - - public ResultCode GetTimeZoneRuleVersion(out UInt128 timeZoneRuleVersion) - { - ResultCode result; - - lock (_lock) - { - if (_isInitialized) - { - timeZoneRuleVersion = _timeZoneRuleVersion; - result = ResultCode.Success; - } - else - { - timeZoneRuleVersion = new UInt128(); - result = ResultCode.UninitializedClock; - } - } - - return result; - } - - public ResultCode ToCalendarTimeWithMyRules(long time, out CalendarInfo calendar) - { - ResultCode result; - - lock (_lock) - { - if (_isInitialized) - { - result = ToCalendarTime(in _myRules.Data, time, out calendar); - } - else - { - calendar = new CalendarInfo(); - result = ResultCode.UninitializedClock; - } - } - - return result; - } - - public ResultCode ToCalendarTime(in TimeZoneRule rules, long time, out CalendarInfo calendar) - { - ResultCode result; - - lock (_lock) - { - result = TimeZone.ToCalendarTime(in rules, time, out calendar); - } - - return result; - } - - public ResultCode ToPosixTimeWithMyRules(CalendarTime calendarTime, out long posixTime) - { - ResultCode result; - - lock (_lock) - { - if (_isInitialized) - { - result = ToPosixTime(in _myRules.Data, calendarTime, out posixTime); - } - else - { - posixTime = 0; - result = ResultCode.UninitializedClock; - } - } - - return result; - } - - public ResultCode ToPosixTime(in TimeZoneRule rules, CalendarTime calendarTime, out long posixTime) - { - ResultCode result; - - lock (_lock) - { - result = TimeZone.ToPosixTime(in rules, calendarTime, out posixTime); - } - - return result; - } - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarAdditionalInfo.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarAdditionalInfo.cs deleted file mode 100644 index a84a2785..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarAdditionalInfo.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Ryujinx.Common.Memory; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.TimeZone -{ - [StructLayout(LayoutKind.Sequential, Pack = 0x4, Size = 0x18, CharSet = CharSet.Ansi)] - struct CalendarAdditionalInfo - { - public uint DayOfWeek; - public uint DayOfYear; - - public Array8<byte> TimezoneName; - - [MarshalAs(UnmanagedType.I1)] - public bool IsDaySavingTime; - - public Array3<byte> Padding; - - public int GmtOffset; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarInfo.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarInfo.cs deleted file mode 100644 index 68e6245b..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarInfo.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.TimeZone -{ - [StructLayout(LayoutKind.Sequential, Pack = 0x4, Size = 0x20, CharSet = CharSet.Ansi)] - struct CalendarInfo - { - public CalendarTime Time; - public CalendarAdditionalInfo AdditionalInfo; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarTime.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarTime.cs deleted file mode 100644 index d594223d..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/CalendarTime.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.TimeZone -{ - [StructLayout(LayoutKind.Sequential, Pack = 0x4, Size = 0x8)] - struct CalendarTime - { - public short Year; - public sbyte Month; - public sbyte Day; - public sbyte Hour; - public sbyte Minute; - public sbyte Second; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeTypeInfo.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeTypeInfo.cs deleted file mode 100644 index b8b3d917..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeTypeInfo.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Ryujinx.Common.Memory; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.TimeZone -{ - [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 4)] - public struct TimeTypeInfo - { - public const int Size = 0x10; - - public int GmtOffset; - - [MarshalAs(UnmanagedType.I1)] - public bool IsDaySavingTime; - - public Array3<byte> Padding1; - - public int AbbreviationListIndex; - - [MarshalAs(UnmanagedType.I1)] - public bool IsStandardTimeDaylight; - - [MarshalAs(UnmanagedType.I1)] - public bool IsGMT; - - public ushort Padding2; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeZoneRule.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeZoneRule.cs deleted file mode 100644 index 67237f3d..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TimeZoneRule.cs +++ /dev/null @@ -1,56 +0,0 @@ -using Ryujinx.Common.Utilities; -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.TimeZone -{ - [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 0x4000, CharSet = CharSet.Ansi)] - public struct TimeZoneRule - { - public const int TzMaxTypes = 128; - public const int TzMaxChars = 50; - public const int TzMaxLeaps = 50; - public const int TzMaxTimes = 1000; - public const int TzNameMax = 255; - public const int TzCharsArraySize = 2 * (TzNameMax + 1); - - public int TimeCount; - public int TypeCount; - public int CharCount; - - [MarshalAs(UnmanagedType.I1)] - public bool GoBack; - - [MarshalAs(UnmanagedType.I1)] - public bool GoAhead; - - [StructLayout(LayoutKind.Sequential, Size = sizeof(long) * TzMaxTimes)] - private struct AtsStorageStruct { } - - private AtsStorageStruct _ats; - - public Span<long> Ats => SpanHelpers.AsSpan<AtsStorageStruct, long>(ref _ats); - - [StructLayout(LayoutKind.Sequential, Size = sizeof(byte) * TzMaxTimes)] - private struct TypesStorageStruct { } - - private TypesStorageStruct _types; - - public Span<byte> Types => SpanHelpers.AsByteSpan(ref _types); - - [StructLayout(LayoutKind.Sequential, Size = TimeTypeInfo.Size * TzMaxTypes)] - private struct TimeTypeInfoStorageStruct { } - - private TimeTypeInfoStorageStruct _ttis; - - public Span<TimeTypeInfo> Ttis => SpanHelpers.AsSpan<TimeTypeInfoStorageStruct, TimeTypeInfo>(ref _ttis); - - [StructLayout(LayoutKind.Sequential, Size = sizeof(byte) * TzCharsArraySize)] - private struct CharsStorageStruct { } - - private CharsStorageStruct _chars; - public Span<byte> Chars => SpanHelpers.AsByteSpan(ref _chars); - - public int DefaultType; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TzifHeader.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TzifHeader.cs deleted file mode 100644 index 022c34a9..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/Types/TzifHeader.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Ryujinx.Common.Memory; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.TimeZone -{ - [StructLayout(LayoutKind.Sequential, Pack = 0x4, Size = 0x2C)] - struct TzifHeader - { - public Array4<byte> Magic; - public byte Version; - private Array15<byte> _reserved; - public int TtisGMTCount; - public int TtisSTDCount; - public int LeapCount; - public int TimeCount; - public int TypeCount; - public int CharCount; - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Time/Types/SteadyClockContext.cs b/Ryujinx.HLE/HOS/Services/Time/Types/SteadyClockContext.cs deleted file mode 100644 index 38d37055..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Types/SteadyClockContext.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.HOS.Services.Time.Types -{ - [StructLayout(LayoutKind.Sequential, Pack = 1)] - struct SteadyClockContext - { - public ulong InternalOffset; - public UInt128 ClockSourceId; - } -} diff --git a/Ryujinx.HLE/HOS/Services/Time/Types/TimePermissions.cs b/Ryujinx.HLE/HOS/Services/Time/Types/TimePermissions.cs deleted file mode 100644 index 3fcd3a14..00000000 --- a/Ryujinx.HLE/HOS/Services/Time/Types/TimePermissions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace Ryujinx.HLE.HOS.Services.Time -{ - [Flags] - enum TimePermissions - { - LocalSystemClockWritableMask = 0x1, - UserSystemClockWritableMask = 0x2, - NetworkSystemClockWritableMask = 0x4, - TimeZoneWritableMask = 0x8, - SteadyClockWritableMask = 0x10, - BypassUninitialized = 0x20, - - User = 0, - Admin = LocalSystemClockWritableMask | UserSystemClockWritableMask | TimeZoneWritableMask, - System = NetworkSystemClockWritableMask, - SystemUpdate = BypassUninitialized, - Repair = SteadyClockWritableMask, - Manufacture = LocalSystemClockWritableMask | UserSystemClockWritableMask | NetworkSystemClockWritableMask | TimeZoneWritableMask | SteadyClockWritableMask - } -} |
