diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index 01b87b425d..f8bb345f22 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -199,7 +199,7 @@ namespace Ryujinx.HLE.HOS // TODO: use set:sys (and set external clock source id from settings) // TODO: use "time!standard_steady_clock_rtc_update_interval_minutes" and implement a worker thread to be accurate. - SteadyClockCore.Instance.ConfigureSetupValue(); + StandardSteadyClockCore.Instance.ConfigureSetupValue(); if (Services.Set.NxSettings.Settings.TryGetValue("time!standard_network_clock_sufficient_accuracy_minutes", out object standardNetworkClockSufficientAccuracyMinutes)) { diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs index 16550199b3..9f18dd2216 100644 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs +++ b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs @@ -4,7 +4,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock { class StandardLocalSystemClockCore : SystemClockCore { - private SteadyClockCore _steadyClockCore; + private StandardSteadyClockCore _steadyClockCore; private SystemClockContext _context; private static StandardLocalSystemClockCore instance; @@ -15,14 +15,14 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock { if (instance == null) { - instance = new StandardLocalSystemClockCore(SteadyClockCore.Instance); + instance = new StandardLocalSystemClockCore(StandardSteadyClockCore.Instance); } return instance; } } - public StandardLocalSystemClockCore(SteadyClockCore steadyClockCore) + public StandardLocalSystemClockCore(StandardSteadyClockCore steadyClockCore) { _steadyClockCore = steadyClockCore; _context = new SystemClockContext(); @@ -37,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock return ResultCode.Success; } - public override SteadyClockCore GetSteadyClockCore() + public override StandardSteadyClockCore GetSteadyClockCore() { return _steadyClockCore; } diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs index c00f460ef5..2b0236cf49 100644 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs +++ b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs @@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock { class StandardNetworkSystemClockCore : SystemClockCore { - private SteadyClockCore _steadyClockCore; + private StandardSteadyClockCore _steadyClockCore; private SystemClockContext _context; private TimeSpanType _standardNetworkClockSufficientAccuracy; @@ -17,14 +17,14 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock { if (instance == null) { - instance = new StandardNetworkSystemClockCore(SteadyClockCore.Instance); + instance = new StandardNetworkSystemClockCore(StandardSteadyClockCore.Instance); } return instance; } } - public StandardNetworkSystemClockCore(SteadyClockCore steadyClockCore) + public StandardNetworkSystemClockCore(StandardSteadyClockCore steadyClockCore) { _steadyClockCore = steadyClockCore; _context = new SystemClockContext(); @@ -40,7 +40,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock return ResultCode.Success; } - public override SteadyClockCore GetSteadyClockCore() + public override StandardSteadyClockCore GetSteadyClockCore() { return _steadyClockCore; } @@ -61,7 +61,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock public bool IsStandardNetworkSystemClockAccuracySufficient(KThread thread) { - SteadyClockCore steadyClockCore = GetSteadyClockCore(); + StandardSteadyClockCore steadyClockCore = GetSteadyClockCore(); SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(thread); bool isStandardNetworkClockSufficientAccuracy = false; diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs new file mode 100644 index 0000000000..32ace04b50 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs @@ -0,0 +1,116 @@ +using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Services.Bpc; +using Ryujinx.HLE.Utilities; +using System; + +namespace Ryujinx.HLE.HOS.Services.Time.Clock +{ + class StandardSteadyClockCore : SteadyClockCore + { + private long _setupValue; + private ResultCode _setupResultCode; + private bool _isRtcResetDetected; + private TimeSpanType _testOffset; + private TimeSpanType _internalOffset; + private UInt128 _clockSourceId; + + private static StandardSteadyClockCore instance; + + public static StandardSteadyClockCore Instance + { + get + { + if (instance == null) + { + instance = new StandardSteadyClockCore(); + } + + return instance; + } + } + + private StandardSteadyClockCore() + { + _testOffset = new TimeSpanType(0); + _internalOffset = new TimeSpanType(0); + _clockSourceId = new UInt128(Guid.NewGuid().ToByteArray()); + } + + public override SteadyClockTimePoint GetTimePoint(KThread thread) + { + SteadyClockTimePoint result = new SteadyClockTimePoint + { + TimePoint = 0, + ClockSourceId = _clockSourceId + }; + + TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(thread.Context.ThreadState.CntpctEl0, thread.Context.ThreadState.CntfrqEl0); + + result.TimePoint = _setupValue + ticksTimeSpan.ToSeconds(); + + return result; + } + + public UInt128 GetClockSourceId() + { + return _clockSourceId; + } + + public override TimeSpanType GetTestOffset() + { + return _testOffset; + } + + public override void SetTestOffset(TimeSpanType testOffset) + { + _testOffset = testOffset; + } + + public override ResultCode GetRtcValue(out ulong rtcValue) + { + return (ResultCode)IRtcManager.GetExternalRtcValue(out rtcValue); + } + + public bool IsRtcResetDetected() + { + return _isRtcResetDetected; + } + + public override TimeSpanType GetInternalOffset() + { + return _internalOffset; + } + + public override void SetInternalOffset(TimeSpanType internalOffset) + { + _internalOffset = internalOffset; + } + + public override ResultCode GetSetupResultValue() + { + return _setupResultCode; + } + + public void ConfigureSetupValue() + { + int retry = 0; + + ResultCode result = ResultCode.Success; + + while (retry < 20) + { + result = (ResultCode)IRtcManager.GetExternalRtcValue(out ulong rtcValue); + + if (result == ResultCode.Success) + { + _setupValue = (long)rtcValue; + break; + } + + retry++; + } + + _setupResultCode = result; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs index 00f296ad07..90e5feef25 100644 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs +++ b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs @@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock return ResultCode.NotImplemented; } - public override SteadyClockCore GetSteadyClockCore() + public override StandardSteadyClockCore GetSteadyClockCore() { return _localSystemClockCore.GetSteadyClockCore(); } diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs index e661ab5380..9942fb3497 100644 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs +++ b/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs @@ -1,131 +1,49 @@ using Ryujinx.HLE.HOS.Kernel.Threading; -using Ryujinx.HLE.HOS.Services.Bpc; -using Ryujinx.HLE.Utilities; using System; namespace Ryujinx.HLE.HOS.Services.Time.Clock { - class SteadyClockCore + abstract class SteadyClockCore { - private long _setupValue; - private ResultCode _setupResultCode; - private bool _isRtcResetDetected; - private TimeSpanType _testOffset; - private TimeSpanType _internalOffset; - private UInt128 _clockSourceId; - - private static SteadyClockCore instance; - - public static SteadyClockCore Instance + public virtual TimeSpanType GetTestOffset() { - get - { - if (instance == null) - { - instance = new SteadyClockCore(); - } - - return instance; - } + return new TimeSpanType(0); } - private SteadyClockCore() + public virtual void SetTestOffset(TimeSpanType testOffset) {} + + public virtual ResultCode GetRtcValue(out ulong rtcValue) { - _testOffset = new TimeSpanType(0); - _internalOffset = new TimeSpanType(0); - _clockSourceId = new UInt128(Guid.NewGuid().ToByteArray()); + rtcValue = 0; + + return ResultCode.NotImplemented; } - private SteadyClockTimePoint GetTimePoint(KThread thread) + public virtual ResultCode GetSetupResultValue() { - SteadyClockTimePoint result = new SteadyClockTimePoint - { - TimePoint = 0, - ClockSourceId = _clockSourceId - }; - - TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(thread.Context.ThreadState.CntpctEl0, thread.Context.ThreadState.CntfrqEl0); - - result.TimePoint = _setupValue + ticksTimeSpan.ToSeconds(); - - return result; + return ResultCode.NotImplemented; } - public UInt128 GetClockSourceId() + public virtual TimeSpanType GetInternalOffset() { - return _clockSourceId; + return new TimeSpanType(0); + } + + public virtual void SetInternalOffset(TimeSpanType internalOffset) {} + + public virtual SteadyClockTimePoint GetTimePoint(KThread thread) + { + throw new NotImplementedException(); } public SteadyClockTimePoint GetCurrentTimePoint(KThread thread) { SteadyClockTimePoint result = GetTimePoint(thread); - result.TimePoint += _testOffset.ToSeconds(); - result.TimePoint += _internalOffset.ToSeconds(); + result.TimePoint += GetTestOffset().ToSeconds(); + result.TimePoint += GetInternalOffset().ToSeconds(); return result; } - - public TimeSpanType GetTestOffset() - { - return _testOffset; - } - - public void SetTestOffset(TimeSpanType testOffset) - { - _testOffset = testOffset; - } - - public ResultCode GetRtcValue(out ulong rtcValue) - { - return (ResultCode)IRtcManager.GetExternalRtcValue(out rtcValue); - } - - public bool IsRtcResetDetected() - { - return _isRtcResetDetected; - } - - public ResultCode GetSetupResultCode() - { - return _setupResultCode; - } - - public TimeSpanType GetInternalOffset() - { - return _internalOffset; - } - - public void SetInternalOffset(TimeSpanType internalOffset) - { - _internalOffset = internalOffset; - } - - public ResultCode GetSetupResultValue() - { - return _setupResultCode; - } - - public void ConfigureSetupValue() - { - int retry = 0; - - ResultCode result = ResultCode.Success; - - while (retry < 20) - { - result = (ResultCode)IRtcManager.GetExternalRtcValue(out ulong rtcValue); - - if (result == ResultCode.Success) - { - _setupValue = (long)rtcValue; - break; - } - - retry++; - } - - _setupResultCode = result; - } } } diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs index d3a056e438..8f6856e41b 100644 --- a/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs +++ b/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs @@ -4,7 +4,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock { abstract class SystemClockCore { - public abstract SteadyClockCore GetSteadyClockCore(); + public abstract StandardSteadyClockCore GetSteadyClockCore(); public abstract ResultCode GetSystemClockContext(KThread thread, out SystemClockContext context); @@ -18,7 +18,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock if (result == ResultCode.Success) { - SteadyClockCore steadyClockCore = GetSteadyClockCore(); + StandardSteadyClockCore steadyClockCore = GetSteadyClockCore(); SteadyClockTimePoint steadyClockTimePoint = steadyClockCore.GetCurrentTimePoint(thread); diff --git a/Ryujinx.HLE/HOS/Services/Time/ISteadyClock.cs b/Ryujinx.HLE/HOS/Services/Time/ISteadyClock.cs index 2772b45d66..7e3edcef9b 100644 --- a/Ryujinx.HLE/HOS/Services/Time/ISteadyClock.cs +++ b/Ryujinx.HLE/HOS/Services/Time/ISteadyClock.cs @@ -9,7 +9,7 @@ namespace Ryujinx.HLE.HOS.Services.Time // GetCurrentTimePoint() -> nn::time::SteadyClockTimePoint public ResultCode GetCurrentTimePoint(ServiceCtx context) { - SteadyClockTimePoint currentTimePoint = SteadyClockCore.Instance.GetCurrentTimePoint(context.Thread); + SteadyClockTimePoint currentTimePoint = StandardSteadyClockCore.Instance.GetCurrentTimePoint(context.Thread); context.ResponseData.WriteStruct(currentTimePoint); @@ -20,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Services.Time // GetTestOffset() -> nn::TimeSpanType public ResultCode GetTestOffset(ServiceCtx context) { - context.ResponseData.WriteStruct(SteadyClockCore.Instance.GetTestOffset()); + context.ResponseData.WriteStruct(StandardSteadyClockCore.Instance.GetTestOffset()); return ResultCode.Success; } @@ -31,7 +31,7 @@ namespace Ryujinx.HLE.HOS.Services.Time { TimeSpanType testOffset = context.RequestData.ReadStruct(); - SteadyClockCore.Instance.SetTestOffset(testOffset); + StandardSteadyClockCore.Instance.SetTestOffset(testOffset); return 0; } @@ -40,7 +40,7 @@ namespace Ryujinx.HLE.HOS.Services.Time // GetRtcValue() -> u64 public ResultCode GetRtcValue(ServiceCtx context) { - ResultCode result = SteadyClockCore.Instance.GetRtcValue(out ulong rtcValue); + ResultCode result = StandardSteadyClockCore.Instance.GetRtcValue(out ulong rtcValue); if (result == ResultCode.Success) { @@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Services.Time // IsRtcResetDetected() -> bool public ResultCode IsRtcResetDetected(ServiceCtx context) { - context.ResponseData.Write(SteadyClockCore.Instance.IsRtcResetDetected()); + context.ResponseData.Write(StandardSteadyClockCore.Instance.IsRtcResetDetected()); return ResultCode.Success; } @@ -63,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Services.Time // GetSetupResultValue() -> u32 public ResultCode GetSetupResultValue(ServiceCtx context) { - context.ResponseData.Write((uint)SteadyClockCore.Instance.GetSetupResultCode()); + context.ResponseData.Write((uint)StandardSteadyClockCore.Instance.GetSetupResultValue()); return ResultCode.Success; } @@ -72,7 +72,7 @@ namespace Ryujinx.HLE.HOS.Services.Time // GetInternalOffset() -> nn::TimeSpanType public ResultCode GetInternalOffset(ServiceCtx context) { - context.ResponseData.WriteStruct(SteadyClockCore.Instance.GetInternalOffset()); + context.ResponseData.WriteStruct(StandardSteadyClockCore.Instance.GetInternalOffset()); return ResultCode.Success; } @@ -83,7 +83,7 @@ namespace Ryujinx.HLE.HOS.Services.Time { TimeSpanType internalOffset = context.RequestData.ReadStruct(); - SteadyClockCore.Instance.SetInternalOffset(internalOffset); + StandardSteadyClockCore.Instance.SetInternalOffset(internalOffset); return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs b/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs index d496dcdc39..7fdb0dd5a8 100644 --- a/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs +++ b/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs @@ -18,7 +18,7 @@ namespace Ryujinx.HLE.HOS.Services.Time // GetCurrentTime() -> nn::time::PosixTime public ResultCode GetCurrentTime(ServiceCtx context) { - SteadyClockCore steadyClockCore = _clockCore.GetSteadyClockCore(); + StandardSteadyClockCore steadyClockCore = _clockCore.GetSteadyClockCore(); SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(context.Thread); ResultCode result = _clockCore.GetSystemClockContext(context.Thread, out SystemClockContext clockContext); @@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Time } long posixTime = context.RequestData.ReadInt64(); - SteadyClockCore steadyClockCore = _clockCore.GetSteadyClockCore(); + StandardSteadyClockCore steadyClockCore = _clockCore.GetSteadyClockCore(); SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(context.Thread); SystemClockContext clockContext = new SystemClockContext()