[Ryujinx.HLE] Address dotnet-format issues (#5380)
* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0052 warnings * Address or silence dotnet format IDE1006 warnings * Address dotnet format CA1816 warnings * Address or silence dotnet format CA2208 warnings * Address or silence dotnet format CA1806 and a few CA1854 warnings * Address dotnet format CA2211 warnings * Address dotnet format CA1822 warnings * Address or silence dotnet format CA1069 warnings * Make dotnet format succeed in style mode * Address or silence dotnet format CA2211 warnings * Address review comments * Address dotnet format CA2208 warnings properly * Make ProcessResult readonly * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Add previously silenced warnings back I have no clue how these disappeared * Revert formatting changes for while and for-loops * Format if-blocks correctly * Run dotnet format style after rebase * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format analyzers after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Fix a few disabled warnings * Fix naming rule violation, Convert shader properties to auto-property and convert values to const * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Start working on disabled warnings * Fix and silence a few dotnet-format warnings again * Run dotnet format after rebase * Use using declaration instead of block syntax * Address IDE0251 warnings * Address a few disabled IDE0060 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Fix naming rule violations * Fix typo * Add trailing commas, use targeted new and use array initializer * Fix build issues * Fix remaining build issues * Remove SuppressMessage for CA1069 where possible * Address dotnet format issues * Address formatting issues Co-authored-by: Ac_K <acoustik666@gmail.com> * Add GetHashCode implementation for RenderingSurfaceInfo * Explicitly silence CA1822 for every affected method in Syscall * Address formatting issues in Demangler.cs * Address review feedback Co-authored-by: Ac_K <acoustik666@gmail.com> * Revert marking service methods as static * Next dotnet format pass * Address review feedback --------- Co-authored-by: Ac_K <acoustik666@gmail.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
{
|
||||
class LocalSystemClockContextWriter : SystemClockContextUpdateCallback
|
||||
{
|
||||
private TimeSharedMemory _sharedMemory;
|
||||
private readonly TimeSharedMemory _sharedMemory;
|
||||
|
||||
public LocalSystemClockContextWriter(TimeSharedMemory sharedMemory)
|
||||
{
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
protected override ResultCode Update()
|
||||
{
|
||||
_sharedMemory.UpdateLocalSystemClockContext(_context);
|
||||
_sharedMemory.UpdateLocalSystemClockContext(Context);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
class NetworkSystemClockContextWriter : SystemClockContextUpdateCallback
|
||||
{
|
||||
private TimeSharedMemory _sharedMemory;
|
||||
private readonly TimeSharedMemory _sharedMemory;
|
||||
|
||||
public NetworkSystemClockContextWriter(TimeSharedMemory sharedMemory)
|
||||
{
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
protected override ResultCode Update()
|
||||
{
|
||||
_sharedMemory.UpdateNetworkSystemClockContext(_context);
|
||||
_sharedMemory.UpdateNetworkSystemClockContext(Context);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
{
|
||||
class StandardLocalSystemClockCore : SystemClockCore
|
||||
{
|
||||
public StandardLocalSystemClockCore(StandardSteadyClockCore steadyClockCore) : base(steadyClockCore) {}
|
||||
public StandardLocalSystemClockCore(StandardSteadyClockCore steadyClockCore) : base(steadyClockCore) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
|
||||
public bool IsStandardNetworkSystemClockAccuracySufficient(ITickSource tickSource)
|
||||
{
|
||||
SteadyClockCore steadyClockCore = GetSteadyClockCore();
|
||||
SteadyClockCore steadyClockCore = GetSteadyClockCore();
|
||||
SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(tickSource);
|
||||
|
||||
bool isStandardNetworkClockSufficientAccuracy = false;
|
||||
|
||||
@@ -11,18 +11,18 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
|
||||
public StandardSteadyClockCore()
|
||||
{
|
||||
_setupValue = TimeSpanType.Zero;
|
||||
_testOffset = TimeSpanType.Zero;
|
||||
_internalOffset = TimeSpanType.Zero;
|
||||
_setupValue = TimeSpanType.Zero;
|
||||
_testOffset = TimeSpanType.Zero;
|
||||
_internalOffset = TimeSpanType.Zero;
|
||||
_cachedRawTimePoint = TimeSpanType.Zero;
|
||||
}
|
||||
|
||||
public override SteadyClockTimePoint GetTimePoint(ITickSource tickSource)
|
||||
{
|
||||
SteadyClockTimePoint result = new SteadyClockTimePoint
|
||||
SteadyClockTimePoint result = new()
|
||||
{
|
||||
TimePoint = GetCurrentRawTimePoint(tickSource).ToSeconds(),
|
||||
ClockSourceId = GetClockSourceId()
|
||||
TimePoint = GetCurrentRawTimePoint(tickSource).ToSeconds(),
|
||||
ClockSourceId = GetClockSourceId(),
|
||||
};
|
||||
|
||||
return result;
|
||||
@@ -52,7 +52,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
{
|
||||
TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency);
|
||||
|
||||
TimeSpanType rawTimePoint = new TimeSpanType(_setupValue.NanoSeconds + ticksTimeSpan.NanoSeconds);
|
||||
TimeSpanType rawTimePoint = new(_setupValue.NanoSeconds + ticksTimeSpan.NanoSeconds);
|
||||
|
||||
if (rawTimePoint.NanoSeconds < _cachedRawTimePoint.NanoSeconds)
|
||||
{
|
||||
|
||||
@@ -6,19 +6,19 @@ 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;
|
||||
private readonly StandardLocalSystemClockCore _localSystemClockCore;
|
||||
private readonly StandardNetworkSystemClockCore _networkSystemClockCore;
|
||||
private bool _autoCorrectionEnabled;
|
||||
private SteadyClockTimePoint _autoCorrectionTime;
|
||||
private KEvent _autoCorrectionEvent;
|
||||
|
||||
public StandardUserSystemClockCore(StandardLocalSystemClockCore localSystemClockCore, StandardNetworkSystemClockCore networkSystemClockCore) : base(localSystemClockCore.GetSteadyClockCore())
|
||||
{
|
||||
_localSystemClockCore = localSystemClockCore;
|
||||
_localSystemClockCore = localSystemClockCore;
|
||||
_networkSystemClockCore = networkSystemClockCore;
|
||||
_autoCorrectionEnabled = false;
|
||||
_autoCorrectionTime = SteadyClockTimePoint.GetRandom();
|
||||
_autoCorrectionEvent = null;
|
||||
_autoCorrectionEnabled = false;
|
||||
_autoCorrectionTime = SteadyClockTimePoint.GetRandom();
|
||||
_autoCorrectionEvent = null;
|
||||
}
|
||||
|
||||
protected override ResultCode Flush(SystemClockContext context)
|
||||
|
||||
@@ -7,14 +7,14 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
abstract class SteadyClockCore
|
||||
{
|
||||
private UInt128 _clockSourceId;
|
||||
private bool _isRtcResetDetected;
|
||||
private bool _isInitialized;
|
||||
private bool _isRtcResetDetected;
|
||||
private bool _isInitialized;
|
||||
|
||||
public SteadyClockCore()
|
||||
{
|
||||
_clockSourceId = UInt128Utils.CreateRandom();
|
||||
_clockSourceId = UInt128Utils.CreateRandom();
|
||||
_isRtcResetDetected = false;
|
||||
_isInitialized = false;
|
||||
_isInitialized = false;
|
||||
}
|
||||
|
||||
public UInt128 GetClockSourceId()
|
||||
@@ -37,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
return new TimeSpanType(0);
|
||||
}
|
||||
|
||||
public virtual void SetTestOffset(TimeSpanType testOffset) {}
|
||||
public virtual void SetTestOffset(TimeSpanType testOffset) { }
|
||||
|
||||
public ResultCode GetRtcValue(out ulong rtcValue)
|
||||
{
|
||||
@@ -61,7 +61,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
return new TimeSpanType(0);
|
||||
}
|
||||
|
||||
public virtual void SetInternalOffset(TimeSpanType internalOffset) {}
|
||||
public virtual void SetInternalOffset(TimeSpanType internalOffset) { }
|
||||
|
||||
public virtual SteadyClockTimePoint GetTimePoint(ITickSource tickSource)
|
||||
{
|
||||
|
||||
@@ -6,22 +6,22 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
{
|
||||
abstract class SystemClockContextUpdateCallback
|
||||
{
|
||||
private List<KWritableEvent> _operationEventList;
|
||||
protected SystemClockContext _context;
|
||||
private bool _hasContext;
|
||||
private readonly List<KWritableEvent> _operationEventList;
|
||||
protected SystemClockContext Context;
|
||||
private bool _hasContext;
|
||||
|
||||
public SystemClockContextUpdateCallback()
|
||||
{
|
||||
_operationEventList = new List<KWritableEvent>();
|
||||
_context = new SystemClockContext();
|
||||
_hasContext = false;
|
||||
Context = new SystemClockContext();
|
||||
_hasContext = false;
|
||||
}
|
||||
|
||||
private bool NeedUpdate(SystemClockContext context)
|
||||
{
|
||||
if (_hasContext)
|
||||
{
|
||||
return _context.Offset != context.Offset || _context.SteadyTimePoint.ClockSourceId != context.SteadyTimePoint.ClockSourceId;
|
||||
return Context.Offset != context.Offset || Context.SteadyTimePoint.ClockSourceId != context.SteadyTimePoint.ClockSourceId;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
|
||||
if (NeedUpdate(context))
|
||||
{
|
||||
_context = context;
|
||||
Context = context;
|
||||
_hasContext = true;
|
||||
|
||||
result = Update();
|
||||
|
||||
@@ -5,19 +5,19 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
{
|
||||
abstract class SystemClockCore
|
||||
{
|
||||
private SteadyClockCore _steadyClockCore;
|
||||
private SystemClockContext _context;
|
||||
private bool _isInitialized;
|
||||
private readonly SteadyClockCore _steadyClockCore;
|
||||
private SystemClockContext _context;
|
||||
private bool _isInitialized;
|
||||
private SystemClockContextUpdateCallback _systemClockContextUpdateCallback;
|
||||
|
||||
public SystemClockCore(SteadyClockCore steadyClockCore)
|
||||
{
|
||||
_steadyClockCore = steadyClockCore;
|
||||
_context = new SystemClockContext();
|
||||
_isInitialized = false;
|
||||
_context = new SystemClockContext();
|
||||
_isInitialized = false;
|
||||
|
||||
_context.SteadyTimePoint.ClockSourceId = steadyClockCore.GetClockSourceId();
|
||||
_systemClockContextUpdateCallback = null;
|
||||
_systemClockContextUpdateCallback = null;
|
||||
}
|
||||
|
||||
public virtual SteadyClockCore GetSteadyClockCore()
|
||||
@@ -52,10 +52,10 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
{
|
||||
SteadyClockTimePoint currentTimePoint = _steadyClockCore.GetCurrentTimePoint(tickSource);
|
||||
|
||||
SystemClockContext clockContext = new SystemClockContext()
|
||||
SystemClockContext clockContext = new()
|
||||
{
|
||||
Offset = posixTime - currentTimePoint.TimePoint,
|
||||
SteadyTimePoint = currentTimePoint
|
||||
Offset = posixTime - currentTimePoint.TimePoint,
|
||||
SteadyTimePoint = currentTimePoint,
|
||||
};
|
||||
|
||||
ResultCode result = SetClockContext(clockContext);
|
||||
@@ -99,10 +99,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
|
||||
public void RegisterOperationEvent(KWritableEvent writableEvent)
|
||||
{
|
||||
if (_systemClockContextUpdateCallback != null)
|
||||
{
|
||||
_systemClockContextUpdateCallback.RegisterOperationEvent(writableEvent);
|
||||
}
|
||||
_systemClockContextUpdateCallback?.RegisterOperationEvent(writableEvent);
|
||||
}
|
||||
|
||||
public ResultCode SetSystemClockContext(SystemClockContext context)
|
||||
|
||||
@@ -4,14 +4,14 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
{
|
||||
class TickBasedSteadyClockCore : SteadyClockCore
|
||||
{
|
||||
public TickBasedSteadyClockCore() {}
|
||||
public TickBasedSteadyClockCore() { }
|
||||
|
||||
public override SteadyClockTimePoint GetTimePoint(ITickSource tickSource)
|
||||
{
|
||||
SteadyClockTimePoint result = new SteadyClockTimePoint
|
||||
SteadyClockTimePoint result = new()
|
||||
{
|
||||
TimePoint = 0,
|
||||
ClockSourceId = GetClockSourceId()
|
||||
TimePoint = 0,
|
||||
ClockSourceId = GetClockSourceId(),
|
||||
};
|
||||
|
||||
TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency);
|
||||
|
||||
@@ -7,23 +7,23 @@ 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 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;
|
||||
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 bool IsAutomaticCorrectionEnabled;
|
||||
public byte Type;
|
||||
public ushort Unknown;
|
||||
|
||||
|
||||
@@ -47,4 +47,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
return ResultCode.TimeMismatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct SteadyClockTimePoint
|
||||
{
|
||||
public long TimePoint;
|
||||
public long TimePoint;
|
||||
public UInt128 ClockSourceId;
|
||||
|
||||
public ResultCode GetSpanBetween(SteadyClockTimePoint other, out long outSpan)
|
||||
public readonly ResultCode GetSpanBetween(SteadyClockTimePoint other, out long outSpan)
|
||||
{
|
||||
outSpan = 0;
|
||||
|
||||
@@ -35,9 +35,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
{
|
||||
return new SteadyClockTimePoint
|
||||
{
|
||||
TimePoint = 0,
|
||||
ClockSourceId = UInt128Utils.CreateRandom()
|
||||
TimePoint = 0,
|
||||
ClockSourceId = UInt128Utils.CreateRandom(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct SystemClockContext
|
||||
{
|
||||
public long Offset;
|
||||
public long Offset;
|
||||
public SteadyClockTimePoint SteadyTimePoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
{
|
||||
private const long NanoSecondsPerSecond = 1000000000;
|
||||
|
||||
public static readonly TimeSpanType Zero = new TimeSpanType(0);
|
||||
public static readonly TimeSpanType Zero = new(0);
|
||||
|
||||
public long NanoSeconds;
|
||||
|
||||
@@ -17,17 +17,17 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
NanoSeconds = nanoSeconds;
|
||||
}
|
||||
|
||||
public long ToSeconds()
|
||||
public readonly long ToSeconds()
|
||||
{
|
||||
return NanoSeconds / NanoSecondsPerSecond;
|
||||
}
|
||||
|
||||
public TimeSpanType AddSeconds(long seconds)
|
||||
public readonly TimeSpanType AddSeconds(long seconds)
|
||||
{
|
||||
return new TimeSpanType(NanoSeconds + (seconds * NanoSecondsPerSecond));
|
||||
}
|
||||
|
||||
public bool IsDaylightSavingTime()
|
||||
public readonly bool IsDaylightSavingTime()
|
||||
{
|
||||
return DateTime.UnixEpoch.AddSeconds(ToSeconds()).ToLocalTime().IsDaylightSavingTime();
|
||||
}
|
||||
@@ -47,4 +47,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
|
||||
return FromSeconds((long)ticks / (long)frequency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
{
|
||||
public IAlarmService(ServiceCtx context) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
{
|
||||
public IPowerStateRequestHandler(ServiceCtx context) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
[Service("time:u", TimePermissions.User)]
|
||||
class IStaticServiceForGlue : IpcService
|
||||
{
|
||||
private IStaticServiceForPsc _inner;
|
||||
private TimePermissions _permissions;
|
||||
private readonly IStaticServiceForPsc _inner;
|
||||
private readonly TimePermissions _permissions;
|
||||
|
||||
public IStaticServiceForGlue(ServiceCtx context, TimePermissions permissions) : base(context.Device.System.TimeServer)
|
||||
{
|
||||
_permissions = permissions;
|
||||
_inner = new IStaticServiceForPsc(context, permissions);
|
||||
_inner = new IStaticServiceForPsc(context, permissions);
|
||||
_inner.TrySetServer(Server);
|
||||
_inner.SetParent(this);
|
||||
}
|
||||
@@ -83,7 +83,9 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
return ResultCode.PermissionDenied;
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
TimeSpanType internalOffset = context.RequestData.ReadStruct<TimeSpanType>();
|
||||
#pragma warning restore IDE0059
|
||||
|
||||
// TODO: set:sys SetExternalSteadyClockInternalOffset(internalOffset.ToSeconds())
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
[Service("time:su", TimePermissions.SystemUpdate)]
|
||||
class IStaticServiceForPsc : IpcService
|
||||
{
|
||||
private TimeManager _timeManager;
|
||||
private TimePermissions _permissions;
|
||||
private readonly TimeManager _timeManager;
|
||||
private readonly TimePermissions _permissions;
|
||||
|
||||
private int _timeSharedMemoryNativeHandle = 0;
|
||||
|
||||
public IStaticServiceForPsc(ServiceCtx context, TimePermissions permissions) : this(TimeManager.Instance, permissions) {}
|
||||
public IStaticServiceForPsc(ServiceCtx context, TimePermissions permissions) : this(TimeManager.Instance, permissions) { }
|
||||
|
||||
public IStaticServiceForPsc(TimeManager manager, TimePermissions permissions)
|
||||
{
|
||||
@@ -149,8 +149,8 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
// SetStandardUserSystemClockAutomaticCorrectionEnabled(b8)
|
||||
public ResultCode SetStandardUserSystemClockAutomaticCorrectionEnabled(ServiceCtx context)
|
||||
{
|
||||
SteadyClockCore steadyClock = _timeManager.StandardSteadyClock;
|
||||
StandardUserSystemClockCore userClock = _timeManager.StandardUserSystemClock;
|
||||
SteadyClockCore steadyClock = _timeManager.StandardSteadyClock;
|
||||
StandardUserSystemClockCore userClock = _timeManager.StandardUserSystemClock;
|
||||
|
||||
if (!userClock.IsInitialized() || !steadyClock.IsInitialized())
|
||||
{
|
||||
@@ -229,7 +229,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
|
||||
ITickSource tickSource = context.Device.System.TickSource;
|
||||
|
||||
SystemClockContext otherContext = context.RequestData.ReadStruct<SystemClockContext>();
|
||||
SystemClockContext otherContext = context.RequestData.ReadStruct<SystemClockContext>();
|
||||
SteadyClockTimePoint currentTimePoint = steadyClock.GetCurrentTimePoint(tickSource);
|
||||
|
||||
ResultCode result = ResultCode.TimeMismatch;
|
||||
@@ -237,7 +237,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
if (currentTimePoint.ClockSourceId == otherContext.SteadyTimePoint.ClockSourceId)
|
||||
{
|
||||
TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency);
|
||||
long baseTimePoint = otherContext.Offset + currentTimePoint.TimePoint - ticksTimeSpan.ToSeconds();
|
||||
long baseTimePoint = otherContext.Offset + currentTimePoint.TimePoint - ticksTimeSpan.ToSeconds();
|
||||
|
||||
context.ResponseData.Write(baseTimePoint);
|
||||
|
||||
@@ -287,7 +287,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
|
||||
context.RequestData.BaseStream.Position += 7;
|
||||
|
||||
SystemClockContext userContext = context.RequestData.ReadStruct<SystemClockContext>();
|
||||
SystemClockContext userContext = context.RequestData.ReadStruct<SystemClockContext>();
|
||||
SystemClockContext networkContext = context.RequestData.ReadStruct<SystemClockContext>();
|
||||
|
||||
ITickSource tickSource = context.Device.System.TickSource;
|
||||
@@ -308,7 +308,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
{
|
||||
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);
|
||||
TimeSpanType difference = TimeSpanType.FromSeconds(clockSnapshotB.UserContext.Offset - clockSnapshotA.UserContext.Offset);
|
||||
|
||||
if (clockSnapshotB.UserContext.SteadyTimePoint.ClockSourceId != clockSnapshotA.UserContext.SteadyTimePoint.ClockSourceId || (clockSnapshotB.IsAutomaticCorrectionEnabled && clockSnapshotA.IsAutomaticCorrectionEnabled))
|
||||
{
|
||||
@@ -337,7 +337,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
|
||||
if (clockSnapshotA.NetworkTime != 0 && clockSnapshotB.NetworkTime != 0)
|
||||
{
|
||||
result = TimeSpanType.FromSeconds(clockSnapshotB.NetworkTime - clockSnapshotA.NetworkTime);
|
||||
result = TimeSpanType.FromSeconds(clockSnapshotB.NetworkTime - clockSnapshotA.NetworkTime);
|
||||
resultCode = ResultCode.Success;
|
||||
}
|
||||
else
|
||||
@@ -359,13 +359,13 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
{
|
||||
clockSnapshot = new ClockSnapshot();
|
||||
|
||||
SteadyClockCore steadyClockCore = _timeManager.StandardSteadyClock;
|
||||
SteadyClockCore steadyClockCore = _timeManager.StandardSteadyClock;
|
||||
SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(tickSource);
|
||||
|
||||
clockSnapshot.IsAutomaticCorrectionEnabled = _timeManager.StandardUserSystemClock.IsAutomaticCorrectionEnabled();
|
||||
clockSnapshot.UserContext = userContext;
|
||||
clockSnapshot.NetworkContext = networkContext;
|
||||
clockSnapshot.SteadyClockTimePoint = currentTimePoint;
|
||||
clockSnapshot.UserContext = userContext;
|
||||
clockSnapshot.NetworkContext = networkContext;
|
||||
clockSnapshot.SteadyClockTimePoint = currentTimePoint;
|
||||
|
||||
ResultCode result = _timeManager.TimeZone.Manager.GetDeviceLocationName(out string deviceLocationName);
|
||||
|
||||
@@ -386,7 +386,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
|
||||
if (result == ResultCode.Success)
|
||||
{
|
||||
clockSnapshot.UserCalendarTime = userCalendarInfo.Time;
|
||||
clockSnapshot.UserCalendarTime = userCalendarInfo.Time;
|
||||
clockSnapshot.UserCalendarAdditionalTime = userCalendarInfo.AdditionalInfo;
|
||||
|
||||
if (ClockSnapshot.GetCurrentTime(out clockSnapshot.NetworkTime, currentTimePoint, clockSnapshot.NetworkContext) != ResultCode.Success)
|
||||
@@ -398,9 +398,9 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
|
||||
if (result == ResultCode.Success)
|
||||
{
|
||||
clockSnapshot.NetworkCalendarTime = networkCalendarInfo.Time;
|
||||
clockSnapshot.NetworkCalendarTime = networkCalendarInfo.Time;
|
||||
clockSnapshot.NetworkCalendarAdditionalTime = networkCalendarInfo.AdditionalInfo;
|
||||
clockSnapshot.Type = type;
|
||||
clockSnapshot.Type = type;
|
||||
|
||||
// Probably a version field?
|
||||
clockSnapshot.Unknown = 0;
|
||||
@@ -419,10 +419,9 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
|
||||
context.Memory.Read(ipcDesc.Position, temp);
|
||||
|
||||
using (BinaryReader bufferReader = new BinaryReader(new MemoryStream(temp)))
|
||||
{
|
||||
return bufferReader.ReadStruct<ClockSnapshot>();
|
||||
}
|
||||
using BinaryReader bufferReader = new(new MemoryStream(temp));
|
||||
|
||||
return bufferReader.ReadStruct<ClockSnapshot>();
|
||||
}
|
||||
|
||||
private void WriteClockSnapshotFromBuffer(ServiceCtx context, IpcRecvListBuffDesc ipcDesc, ClockSnapshot clockSnapshot)
|
||||
@@ -430,4 +429,4 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
MemoryHelper.Write(context.Memory, ipcDesc.Position, clockSnapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
[Service("time:m")] // 9.0.0+
|
||||
class ITimeServiceManager : IpcService
|
||||
{
|
||||
private TimeManager _timeManager;
|
||||
private int _automaticCorrectionEvent;
|
||||
private readonly TimeManager _timeManager;
|
||||
private int _automaticCorrectionEvent;
|
||||
|
||||
public ITimeServiceManager(ServiceCtx context)
|
||||
{
|
||||
_timeManager = TimeManager.Instance;
|
||||
_timeManager = TimeManager.Instance;
|
||||
_automaticCorrectionEvent = 0;
|
||||
}
|
||||
|
||||
@@ -62,11 +62,11 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
// 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();
|
||||
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;
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
public ResultCode SetupStandardLocalSystemClock(ServiceCtx context)
|
||||
{
|
||||
SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>();
|
||||
long posixTime = context.RequestData.ReadInt64();
|
||||
long posixTime = context.RequestData.ReadInt64();
|
||||
|
||||
ITickSource tickSource = context.Device.System.TickSource;
|
||||
|
||||
@@ -93,8 +93,8 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
// 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>();
|
||||
SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>();
|
||||
TimeSpanType sufficientAccuracy = context.RequestData.ReadStruct<TimeSpanType>();
|
||||
|
||||
_timeManager.SetupStandardNetworkSystemClock(clockContext, sufficientAccuracy);
|
||||
|
||||
@@ -122,10 +122,10 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
// 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);
|
||||
string locationName = StringUtils.ReadInlinedAsciiString(context.RequestData, 0x24);
|
||||
SteadyClockTimePoint timeZoneUpdateTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>();
|
||||
uint totalLocationNameCount = context.RequestData.ReadUInt32();
|
||||
UInt128 timeZoneRuleVersion = context.RequestData.ReadStruct<UInt128>();
|
||||
uint totalLocationNameCount = context.RequestData.ReadUInt32();
|
||||
UInt128 timeZoneRuleVersion = context.RequestData.ReadStruct<UInt128>();
|
||||
|
||||
(ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21();
|
||||
|
||||
@@ -133,10 +133,9 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
|
||||
context.Memory.Read(bufferPosition, temp);
|
||||
|
||||
using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp))
|
||||
{
|
||||
_timeManager.SetupTimeZoneManager(locationName, timeZoneUpdateTimePoint, totalLocationNameCount, timeZoneRuleVersion, timeZoneBinaryStream);
|
||||
}
|
||||
using MemoryStream timeZoneBinaryStream = new(temp);
|
||||
|
||||
_timeManager.SetupTimeZoneManager(locationName, timeZoneUpdateTimePoint, totalLocationNameCount, timeZoneRuleVersion, timeZoneBinaryStream);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Time
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Time
|
||||
{
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
public enum ResultCode
|
||||
{
|
||||
ModuleId = 116,
|
||||
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,
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
{
|
||||
class ISteadyClock : IpcService
|
||||
{
|
||||
private SteadyClockCore _steadyClock;
|
||||
private bool _writePermission;
|
||||
private bool _bypassUninitializedClock;
|
||||
private readonly SteadyClockCore _steadyClock;
|
||||
private readonly bool _writePermission;
|
||||
private readonly bool _bypassUninitializedClock;
|
||||
|
||||
public ISteadyClock(SteadyClockCore steadyClock, bool writePermission, bool bypassUninitializedClock)
|
||||
{
|
||||
_steadyClock = steadyClock;
|
||||
_writePermission = writePermission;
|
||||
_steadyClock = steadyClock;
|
||||
_writePermission = writePermission;
|
||||
_bypassUninitializedClock = bypassUninitializedClock;
|
||||
}
|
||||
|
||||
@@ -152,4 +152,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,16 +10,16 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
{
|
||||
class ISystemClock : IpcService
|
||||
{
|
||||
private SystemClockCore _clockCore;
|
||||
private bool _writePermission;
|
||||
private bool _bypassUninitializedClock;
|
||||
private int _operationEventReadableHandle;
|
||||
private readonly SystemClockCore _clockCore;
|
||||
private readonly bool _writePermission;
|
||||
private readonly bool _bypassUninitializedClock;
|
||||
private int _operationEventReadableHandle;
|
||||
|
||||
public ISystemClock(SystemClockCore clockCore, bool writePermission, bool bypassUninitializedClock)
|
||||
{
|
||||
_clockCore = clockCore;
|
||||
_writePermission = writePermission;
|
||||
_bypassUninitializedClock = bypassUninitializedClock;
|
||||
_clockCore = clockCore;
|
||||
_writePermission = writePermission;
|
||||
_bypassUninitializedClock = bypassUninitializedClock;
|
||||
_operationEventReadableHandle = 0;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
{
|
||||
if (_operationEventReadableHandle == 0)
|
||||
{
|
||||
KEvent kEvent = new KEvent(context.Device.System.KernelContext);
|
||||
KEvent kEvent = new(context.Device.System.KernelContext);
|
||||
|
||||
_clockCore.RegisterOperationEvent(kEvent.WritableEvent);
|
||||
|
||||
@@ -128,4 +128,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,15 +12,15 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
{
|
||||
class ITimeZoneServiceForGlue : IpcService
|
||||
{
|
||||
private TimeZoneContentManager _timeZoneContentManager;
|
||||
private ITimeZoneServiceForPsc _inner;
|
||||
private bool _writePermission;
|
||||
private readonly TimeZoneContentManager _timeZoneContentManager;
|
||||
private readonly ITimeZoneServiceForPsc _inner;
|
||||
private readonly bool _writePermission;
|
||||
|
||||
public ITimeZoneServiceForGlue(TimeZoneContentManager timeZoneContentManager, bool writePermission)
|
||||
{
|
||||
_timeZoneContentManager = timeZoneContentManager;
|
||||
_writePermission = writePermission;
|
||||
_inner = new ITimeZoneServiceForPsc(timeZoneContentManager.Manager, writePermission);
|
||||
_writePermission = writePermission;
|
||||
_inner = new ITimeZoneServiceForPsc(timeZoneContentManager.Manager, writePermission);
|
||||
}
|
||||
|
||||
[CommandCmif(0)]
|
||||
@@ -55,9 +55,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
// LoadLocationNameList(u32 index) -> (u32 outCount, buffer<nn::time::LocationName, 6>)
|
||||
public ResultCode LoadLocationNameList(ServiceCtx context)
|
||||
{
|
||||
uint index = context.RequestData.ReadUInt32();
|
||||
uint index = context.RequestData.ReadUInt32();
|
||||
ulong bufferPosition = context.Request.ReceiveBuff[0].Position;
|
||||
ulong bufferSize = context.Request.ReceiveBuff[0].Size;
|
||||
ulong bufferSize = context.Request.ReceiveBuff[0].Size;
|
||||
|
||||
ResultCode errorCode = _timeZoneContentManager.LoadLocationNameList(index, out string[] locationNameArray, (uint)bufferSize / 0x24);
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
public ResultCode LoadTimeZoneRule(ServiceCtx context)
|
||||
{
|
||||
ulong bufferPosition = context.Request.ReceiveBuff[0].Position;
|
||||
ulong bufferSize = context.Request.ReceiveBuff[0].Size;
|
||||
ulong bufferSize = context.Request.ReceiveBuff[0].Size;
|
||||
|
||||
if (bufferSize != 0x4000)
|
||||
{
|
||||
@@ -103,12 +103,11 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
|
||||
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];
|
||||
using WritableRegion region = context.Memory.GetWritableRegion(bufferPosition, Unsafe.SizeOf<TimeZoneRule>());
|
||||
|
||||
return _timeZoneContentManager.LoadTimeZoneRule(ref rules, locationName);
|
||||
}
|
||||
ref TimeZoneRule rules = ref MemoryMarshal.Cast<byte, TimeZoneRule>(region.Memory.Span)[0];
|
||||
|
||||
return _timeZoneContentManager.LoadTimeZoneRule(ref rules, locationName);
|
||||
}
|
||||
|
||||
[CommandCmif(100)]
|
||||
@@ -139,4 +138,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
return _inner.ToPosixTimeWithMyRule(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
{
|
||||
class ITimeZoneServiceForPsc : IpcService
|
||||
{
|
||||
private TimeZoneManager _timeZoneManager;
|
||||
private bool _writePermission;
|
||||
private readonly TimeZoneManager _timeZoneManager;
|
||||
private readonly bool _writePermission;
|
||||
|
||||
public ITimeZoneServiceForPsc(TimeZoneManager timeZoneManager, bool writePermission)
|
||||
{
|
||||
@@ -134,10 +134,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
|
||||
context.Memory.Read(bufferPosition, temp);
|
||||
|
||||
using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp))
|
||||
{
|
||||
result = _timeZoneManager.SetDeviceLocationNameWithTimeZoneRule(locationName, timeZoneBinaryStream);
|
||||
}
|
||||
using MemoryStream timeZoneBinaryStream = new(temp);
|
||||
result = _timeZoneManager.SetDeviceLocationNameWithTimeZoneRule(locationName, timeZoneBinaryStream);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -149,7 +147,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
(ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21();
|
||||
|
||||
ulong timeZoneRuleBufferPosition = context.Request.ReceiveBuff[0].Position;
|
||||
ulong timeZoneRuleBufferSize = context.Request.ReceiveBuff[0].Size;
|
||||
ulong timeZoneRuleBufferSize = context.Request.ReceiveBuff[0].Size;
|
||||
|
||||
if (timeZoneRuleBufferSize != 0x4000)
|
||||
{
|
||||
@@ -165,15 +163,12 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
|
||||
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];
|
||||
using MemoryStream timeZoneBinaryStream = new(temp);
|
||||
using WritableRegion region = context.Memory.GetWritableRegion(timeZoneRuleBufferPosition, Unsafe.SizeOf<TimeZoneRule>());
|
||||
|
||||
result = _timeZoneManager.ParseTimeZoneRuleBinary(ref rule, timeZoneBinaryStream);
|
||||
}
|
||||
}
|
||||
ref TimeZoneRule rule = ref MemoryMarshal.Cast<byte, TimeZoneRule>(region.Memory.Span)[0];
|
||||
|
||||
result = _timeZoneManager.ParseTimeZoneRuleBinary(ref rule, timeZoneBinaryStream);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -189,9 +184,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
// 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();
|
||||
long posixTime = context.RequestData.ReadInt64();
|
||||
ulong bufferPosition = context.Request.SendBuff[0].Position;
|
||||
ulong bufferSize = context.Request.SendBuff[0].Size;
|
||||
ulong bufferSize = context.Request.SendBuff[0].Size;
|
||||
|
||||
if (bufferSize != 0x4000)
|
||||
{
|
||||
@@ -234,7 +229,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
public ResultCode ToPosixTime(ServiceCtx context)
|
||||
{
|
||||
ulong inBufferPosition = context.Request.SendBuff[0].Position;
|
||||
ulong inBufferSize = context.Request.SendBuff[0].Size;
|
||||
ulong inBufferSize = context.Request.SendBuff[0].Size;
|
||||
|
||||
CalendarTime calendarTime = context.RequestData.ReadStruct<CalendarTime>();
|
||||
|
||||
@@ -253,7 +248,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
if (resultCode == ResultCode.Success)
|
||||
{
|
||||
ulong outBufferPosition = context.Request.RecvListBuff[0].Position;
|
||||
ulong outBufferSize = context.Request.RecvListBuff[0].Size;
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
ulong outBufferSize = context.Request.RecvListBuff[0].Size;
|
||||
#pragma warning restore IDE0059
|
||||
|
||||
context.Memory.Write(outBufferPosition, posixTime);
|
||||
context.ResponseData.Write(1);
|
||||
@@ -273,7 +270,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.StaticService
|
||||
if (resultCode == ResultCode.Success)
|
||||
{
|
||||
ulong outBufferPosition = context.Request.RecvListBuff[0].Position;
|
||||
ulong outBufferSize = context.Request.RecvListBuff[0].Size;
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
ulong outBufferSize = context.Request.RecvListBuff[0].Size;
|
||||
#pragma warning restore IDE0059
|
||||
|
||||
context.Memory.Write(outBufferPosition, posixTime);
|
||||
|
||||
|
||||
@@ -16,41 +16,38 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new TimeManager();
|
||||
}
|
||||
_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 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();
|
||||
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);
|
||||
SharedMemory = new TimeSharedMemory();
|
||||
LocalClockContextWriter = new LocalSystemClockContextWriter(SharedMemory);
|
||||
NetworkClockContextWriter = new NetworkSystemClockContextWriter(SharedMemory);
|
||||
EphemeralClockContextWriter = new EphemeralNetworkSystemClockContextWriter();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,12 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
{
|
||||
class TimeSharedMemory
|
||||
{
|
||||
private Switch _device;
|
||||
private KSharedMemory _sharedMemory;
|
||||
private Switch _device;
|
||||
private KSharedMemory _sharedMemory;
|
||||
private SharedMemoryStorage _timeSharedMemoryStorage;
|
||||
private int _timeSharedMemorySize;
|
||||
#pragma warning disable IDE0052 // Remove unread private member
|
||||
private int _timeSharedMemorySize;
|
||||
#pragma warning restore IDE0052
|
||||
|
||||
private const uint SteadyClockContextOffset = 0x00;
|
||||
private const uint LocalSystemClockContextOffset = 0x38;
|
||||
@@ -24,10 +26,10 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
|
||||
public void Initialize(Switch device, KSharedMemory sharedMemory, SharedMemoryStorage timeSharedMemoryStorage, int timeSharedMemorySize)
|
||||
{
|
||||
_device = device;
|
||||
_sharedMemory = sharedMemory;
|
||||
_device = device;
|
||||
_sharedMemory = sharedMemory;
|
||||
_timeSharedMemoryStorage = timeSharedMemoryStorage;
|
||||
_timeSharedMemorySize = timeSharedMemorySize;
|
||||
_timeSharedMemorySize = timeSharedMemorySize;
|
||||
|
||||
// Clean the shared memory
|
||||
timeSharedMemoryStorage.ZeroFill();
|
||||
@@ -60,7 +62,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
{
|
||||
TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency);
|
||||
|
||||
ContinuousAdjustmentTimePoint adjustmentTimePoint = new ContinuousAdjustmentTimePoint
|
||||
ContinuousAdjustmentTimePoint adjustmentTimePoint = new()
|
||||
{
|
||||
ClockOffset = (ulong)ticksTimeSpan.NanoSeconds,
|
||||
Multiplier = 1,
|
||||
@@ -71,17 +73,17 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
SteadyTimePoint = new SteadyClockTimePoint
|
||||
{
|
||||
ClockSourceId = clockSourceId,
|
||||
TimePoint = 0
|
||||
}
|
||||
}
|
||||
TimePoint = 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
WriteObjectToSharedMemory(ContinuousAdjustmentTimePointOffset, 4, adjustmentTimePoint);
|
||||
|
||||
SteadyClockContext context = new SteadyClockContext
|
||||
SteadyClockContext context = new()
|
||||
{
|
||||
InternalOffset = (ulong)(currentTimePoint.NanoSeconds - ticksTimeSpan.NanoSeconds),
|
||||
ClockSourceId = clockSourceId
|
||||
ClockSourceId = clockSourceId,
|
||||
};
|
||||
|
||||
WriteObjectToSharedMemory(SteadyClockContextOffset, 4, context);
|
||||
@@ -99,7 +101,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
|
||||
private T ReadObjectFromSharedMemory<T>(ulong offset, ulong padding) where T : unmanaged
|
||||
{
|
||||
T result;
|
||||
T result;
|
||||
uint index;
|
||||
uint possiblyNewIndex;
|
||||
|
||||
|
||||
@@ -8,36 +8,34 @@ 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 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 MinutesPerHour = 60;
|
||||
private const int HoursPerDays = 24;
|
||||
private const int DaysPerWeek = 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 int YearsPerRepeat = 400;
|
||||
private const long AverageSecondsPerYear = 31556952;
|
||||
private const long SecondsPerRepeat = YearsPerRepeat * AverageSecondsPerYear;
|
||||
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 readonly int[] _yearLengths = { DaysPerNYear, DaysPerLYear };
|
||||
private static readonly int[][] _monthsLengths = {
|
||||
new[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||
new[] { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||
};
|
||||
|
||||
private static ReadOnlySpan<byte> TimeZoneDefaultRule => ",M4.1.0,M10.5.0"u8;
|
||||
@@ -46,14 +44,14 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
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 long Year;
|
||||
public sbyte Month;
|
||||
public sbyte Day;
|
||||
public sbyte Hour;
|
||||
public sbyte Minute;
|
||||
public sbyte Second;
|
||||
|
||||
public int CompareTo(CalendarTimeInternal other)
|
||||
public readonly int CompareTo(CalendarTimeInternal other)
|
||||
{
|
||||
if (Year != other.Year)
|
||||
{
|
||||
@@ -98,16 +96,16 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
JulianDay,
|
||||
DayOfYear,
|
||||
MonthNthDayOfWeek
|
||||
MonthNthDayOfWeek,
|
||||
}
|
||||
|
||||
private struct Rule
|
||||
{
|
||||
public RuleType Type;
|
||||
public int Day;
|
||||
public int Week;
|
||||
public int Month;
|
||||
public int TransitionTime;
|
||||
public int Day;
|
||||
public int Week;
|
||||
public int Month;
|
||||
public int TransitionTime;
|
||||
}
|
||||
|
||||
private static int Detzcode32(ReadOnlySpan<byte> bytes)
|
||||
@@ -145,10 +143,10 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
TimeTypeInfo a = outRules.Ttis[aIndex];
|
||||
TimeTypeInfo b = outRules.Ttis[bIndex];
|
||||
|
||||
return a.GmtOffset == b.GmtOffset &&
|
||||
a.IsDaySavingTime == b.IsDaySavingTime &&
|
||||
return a.GmtOffset == b.GmtOffset &&
|
||||
a.IsDaySavingTime == b.IsDaySavingTime &&
|
||||
a.IsStandardTimeDaylight == b.IsStandardTimeDaylight &&
|
||||
a.IsGMT == b.IsGMT &&
|
||||
a.IsGMT == b.IsGMT &&
|
||||
StringUtils.CompareCStr(outRules.Chars[a.AbbreviationListIndex..], outRules.Chars[b.AbbreviationListIndex..]) == 0;
|
||||
}
|
||||
|
||||
@@ -224,7 +222,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
seconds = 0;
|
||||
|
||||
|
||||
bool isValid = GetNum(name, ref namePosition, out int num, 0, HoursPerDays * DaysPerWekk - 1);
|
||||
bool isValid = GetNum(name, ref namePosition, out int num, 0, HoursPerDays * DaysPerWeek - 1);
|
||||
if (!isValid)
|
||||
{
|
||||
return false;
|
||||
@@ -310,7 +308,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
rule = new Rule();
|
||||
|
||||
bool isValid = false;
|
||||
bool isValid;
|
||||
|
||||
if (name[namePosition] == 'J')
|
||||
{
|
||||
@@ -347,7 +345,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
return false;
|
||||
}
|
||||
|
||||
isValid = GetNum(name, ref namePosition, out rule.Day, 0, DaysPerWekk - 1);
|
||||
isValid = GetNum(name, ref namePosition, out rule.Day, 0, DaysPerWeek - 1);
|
||||
}
|
||||
else if (char.IsDigit((char)name[namePosition]))
|
||||
{
|
||||
@@ -391,7 +389,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
outRules = new TimeZoneRule();
|
||||
|
||||
int stdLen;
|
||||
int stdLen;
|
||||
|
||||
ReadOnlySpan<byte> stdName = name;
|
||||
int namePosition = 0;
|
||||
@@ -408,7 +406,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
namePosition++;
|
||||
|
||||
stdName = name.Slice(namePosition);
|
||||
stdName = name[namePosition..];
|
||||
|
||||
int stdNamePosition = namePosition;
|
||||
|
||||
@@ -442,10 +440,10 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
}
|
||||
|
||||
int charCount = stdLen + 1;
|
||||
int destLen = 0;
|
||||
int destLen = 0;
|
||||
int dstOffset = 0;
|
||||
|
||||
ReadOnlySpan<byte> destName = name.Slice(namePosition);
|
||||
ReadOnlySpan<byte> destName = name[namePosition..];
|
||||
|
||||
if (TzCharsArraySize < charCount)
|
||||
{
|
||||
@@ -456,7 +454,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
if (name[namePosition] == '<')
|
||||
{
|
||||
destName = name.Slice(++namePosition);
|
||||
destName = name[++namePosition..];
|
||||
int destNamePosition = namePosition;
|
||||
|
||||
namePosition = GetQZName(name.ToArray(), namePosition, '>');
|
||||
@@ -471,9 +469,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
}
|
||||
else
|
||||
{
|
||||
destName = name.Slice(namePosition);
|
||||
destName = name[namePosition..];
|
||||
namePosition = GetTZName(name, namePosition);
|
||||
destLen = namePosition;
|
||||
destLen = namePosition;
|
||||
}
|
||||
|
||||
if (destLen == 0)
|
||||
@@ -511,8 +509,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
namePosition++;
|
||||
|
||||
bool IsRuleValid = GetRule(name, ref namePosition, out Rule start);
|
||||
if (!IsRuleValid)
|
||||
bool isRuleValid = GetRule(name, ref namePosition, out Rule start);
|
||||
if (!isRuleValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -522,8 +520,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
return false;
|
||||
}
|
||||
|
||||
IsRuleValid = GetRule(name, ref namePosition, out Rule end);
|
||||
if (!IsRuleValid)
|
||||
isRuleValid = GetRule(name, ref namePosition, out Rule end);
|
||||
if (!isRuleValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -537,28 +535,28 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
outRules.Ttis[0] = new TimeTypeInfo
|
||||
{
|
||||
GmtOffset = -dstOffset,
|
||||
IsDaySavingTime = true,
|
||||
AbbreviationListIndex = stdLen + 1
|
||||
GmtOffset = -dstOffset,
|
||||
IsDaySavingTime = true,
|
||||
AbbreviationListIndex = stdLen + 1,
|
||||
};
|
||||
|
||||
outRules.Ttis[1] = new TimeTypeInfo
|
||||
{
|
||||
GmtOffset = -stdOffset,
|
||||
IsDaySavingTime = false,
|
||||
AbbreviationListIndex = 0
|
||||
GmtOffset = -stdOffset,
|
||||
IsDaySavingTime = false,
|
||||
AbbreviationListIndex = 0,
|
||||
};
|
||||
|
||||
outRules.DefaultType = 0;
|
||||
|
||||
int timeCount = 0;
|
||||
long janFirst = 0;
|
||||
int janOffset = 0;
|
||||
int yearBegining = EpochYear;
|
||||
int timeCount = 0;
|
||||
long janFirst = 0;
|
||||
int janOffset = 0;
|
||||
int yearBegining = EpochYear;
|
||||
|
||||
do
|
||||
{
|
||||
int yearSeconds = YearLengths[IsLeap(yearBegining - 1)] * SecondsPerDay;
|
||||
int yearSeconds = _yearLengths[IsLeap(yearBegining - 1)] * SecondsPerDay;
|
||||
yearBegining--;
|
||||
if (IncrementOverflow64(ref janFirst, -yearSeconds))
|
||||
{
|
||||
@@ -573,17 +571,14 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
for (year = yearBegining; year < yearLimit; year++)
|
||||
{
|
||||
int startTime = TransitionTime(year, start, stdOffset);
|
||||
int endTime = TransitionTime(year, end, dstOffset);
|
||||
int endTime = TransitionTime(year, end, dstOffset);
|
||||
|
||||
int yearSeconds = YearLengths[IsLeap(year)] * SecondsPerDay;
|
||||
int yearSeconds = _yearLengths[IsLeap(year)] * SecondsPerDay;
|
||||
|
||||
bool isReversed = endTime < startTime;
|
||||
if (isReversed)
|
||||
{
|
||||
int swap = startTime;
|
||||
|
||||
startTime = endTime;
|
||||
endTime = swap;
|
||||
(endTime, startTime) = (startTime, endTime);
|
||||
}
|
||||
|
||||
if (isReversed || (startTime < endTime && (endTime - startTime < (yearSeconds + (stdOffset - dstOffset)))))
|
||||
@@ -632,7 +627,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
}
|
||||
else if (YearsPerRepeat < year - yearBegining)
|
||||
{
|
||||
outRules.GoBack = true;
|
||||
outRules.GoBack = true;
|
||||
outRules.GoAhead = true;
|
||||
}
|
||||
}
|
||||
@@ -653,18 +648,22 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
}
|
||||
}
|
||||
|
||||
long theirDstOffset = 0;
|
||||
long theirDstOffset;
|
||||
for (int i = 0; i < outRules.TimeCount; i++)
|
||||
{
|
||||
int j = outRules.Types[i];
|
||||
if (outRules.Ttis[j].IsDaySavingTime)
|
||||
{
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
theirDstOffset = -outRules.Ttis[j].GmtOffset;
|
||||
#pragma warning restore IDE0059
|
||||
}
|
||||
}
|
||||
|
||||
bool isDaySavingTime = false;
|
||||
long theirOffset = theirStdOffset;
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
long theirOffset = theirStdOffset;
|
||||
#pragma warning restore IDE0059
|
||||
for (int i = 0; i < outRules.TimeCount; i++)
|
||||
{
|
||||
int j = outRules.Types[i];
|
||||
@@ -684,7 +683,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
theirOffset = -outRules.Ttis[j].GmtOffset;
|
||||
if (outRules.Ttis[j].IsDaySavingTime)
|
||||
{
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
theirDstOffset = theirOffset;
|
||||
#pragma warning restore IDE0059
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -694,33 +695,33 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
outRules.Ttis[0] = new TimeTypeInfo
|
||||
{
|
||||
GmtOffset = -stdOffset,
|
||||
IsDaySavingTime = false,
|
||||
AbbreviationListIndex = 0
|
||||
GmtOffset = -stdOffset,
|
||||
IsDaySavingTime = false,
|
||||
AbbreviationListIndex = 0,
|
||||
};
|
||||
|
||||
outRules.Ttis[1] = new TimeTypeInfo
|
||||
{
|
||||
GmtOffset = -dstOffset,
|
||||
IsDaySavingTime = true,
|
||||
AbbreviationListIndex = stdLen + 1
|
||||
GmtOffset = -dstOffset,
|
||||
IsDaySavingTime = true,
|
||||
AbbreviationListIndex = stdLen + 1,
|
||||
};
|
||||
|
||||
outRules.TypeCount = 2;
|
||||
outRules.TypeCount = 2;
|
||||
outRules.DefaultType = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// default is perpetual standard time
|
||||
outRules.TypeCount = 1;
|
||||
outRules.TimeCount = 0;
|
||||
outRules.TypeCount = 1;
|
||||
outRules.TimeCount = 0;
|
||||
outRules.DefaultType = 0;
|
||||
outRules.Ttis[0] = new TimeTypeInfo
|
||||
outRules.Ttis[0] = new TimeTypeInfo
|
||||
{
|
||||
GmtOffset = -stdOffset,
|
||||
IsDaySavingTime = false,
|
||||
AbbreviationListIndex = 0
|
||||
GmtOffset = -stdOffset,
|
||||
IsDaySavingTime = false,
|
||||
AbbreviationListIndex = 0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -770,7 +771,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
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 m1 = (rule.Month + 9) % 12 + 1;
|
||||
int yy0 = (rule.Month <= 2) ? (year - 1) : year;
|
||||
int yy1 = yy0 / 100;
|
||||
int yy2 = yy0 % 100;
|
||||
@@ -779,7 +780,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
if (dayOfWeek < 0)
|
||||
{
|
||||
dayOfWeek += DaysPerWekk;
|
||||
dayOfWeek += DaysPerWeek;
|
||||
}
|
||||
|
||||
// Get the zero origin
|
||||
@@ -787,23 +788,23 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
if (d < 0)
|
||||
{
|
||||
d += DaysPerWekk;
|
||||
d += DaysPerWeek;
|
||||
}
|
||||
|
||||
for (int i = 1; i < rule.Week; i++)
|
||||
{
|
||||
if (d + DaysPerWekk >= MonthsLengths[leapYear][rule.Month - 1])
|
||||
if (d + DaysPerWeek >= _monthsLengths[leapYear][rule.Month - 1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
d += DaysPerWekk;
|
||||
d += DaysPerWeek;
|
||||
}
|
||||
|
||||
value = d * SecondsPerDay;
|
||||
for (int i = 0; i < rule.Month - 1; i++)
|
||||
{
|
||||
value += MonthsLengths[leapYear][i] * SecondsPerDay;
|
||||
value += _monthsLengths[leapYear][i] * SecondsPerDay;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -887,7 +888,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
outRules = new TimeZoneRule();
|
||||
|
||||
BinaryReader reader = new BinaryReader(inputData);
|
||||
BinaryReader reader = new(inputData);
|
||||
|
||||
long streamLength = reader.BaseStream.Length;
|
||||
|
||||
@@ -902,10 +903,10 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
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);
|
||||
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
|
||||
@@ -1053,7 +1054,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
}
|
||||
|
||||
long position = (workBuffer.Length - p.Length);
|
||||
long nRead = streamLength - position;
|
||||
long nRead = streamLength - position;
|
||||
|
||||
if (nRead < 0)
|
||||
{
|
||||
@@ -1077,7 +1078,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
byte[] name = new byte[TzNameMax];
|
||||
Array.Copy(tempName, 1, name, 0, nRead - 1);
|
||||
|
||||
Box<TimeZoneRule> tempRulesBox = new Box<TimeZoneRule>();
|
||||
Box<TimeZoneRule> tempRulesBox = new();
|
||||
ref TimeZoneRule tempRules = ref tempRulesBox.Data;
|
||||
|
||||
if (ParsePosixName(name, ref tempRulesBox.Data, false))
|
||||
@@ -1247,17 +1248,17 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
private static ResultCode CreateCalendarTime(long time, int gmtOffset, out CalendarTimeInternal calendarTime, out CalendarAdditionalInfo calendarAdditionalInfo)
|
||||
{
|
||||
long year = EpochYear;
|
||||
long timeDays = time / SecondsPerDay;
|
||||
long year = EpochYear;
|
||||
long timeDays = time / SecondsPerDay;
|
||||
long remainingSeconds = time % SecondsPerDay;
|
||||
|
||||
calendarTime = new CalendarTimeInternal();
|
||||
calendarTime = new CalendarTimeInternal();
|
||||
calendarAdditionalInfo = new CalendarAdditionalInfo();
|
||||
|
||||
while (timeDays < 0 || timeDays >= YearLengths[IsLeap((int)year)])
|
||||
while (timeDays < 0 || timeDays >= _yearLengths[IsLeap((int)year)])
|
||||
{
|
||||
long timeDelta = timeDays / DaysPerLYear;
|
||||
long delta = timeDelta;
|
||||
long delta = timeDelta;
|
||||
|
||||
if (delta == 0)
|
||||
{
|
||||
@@ -1298,12 +1299,12 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
return ResultCode.OutOfRange;
|
||||
}
|
||||
|
||||
dayOfYear += YearLengths[IsLeap((int)year)];
|
||||
dayOfYear += _yearLengths[IsLeap((int)year)];
|
||||
}
|
||||
|
||||
while (dayOfYear >= YearLengths[IsLeap((int)year)])
|
||||
while (dayOfYear >= _yearLengths[IsLeap((int)year)])
|
||||
{
|
||||
dayOfYear -= YearLengths[IsLeap((int)year)];
|
||||
dayOfYear -= _yearLengths[IsLeap((int)year)];
|
||||
|
||||
if (IncrementOverflow64(ref year, 1))
|
||||
{
|
||||
@@ -1311,13 +1312,13 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
}
|
||||
}
|
||||
|
||||
calendarTime.Year = year;
|
||||
calendarTime.Year = year;
|
||||
calendarAdditionalInfo.DayOfYear = (uint)dayOfYear;
|
||||
|
||||
long dayOfWeek = (EpochWeekDay + ((year - EpochYear) % DaysPerWekk) * (DaysPerNYear % DaysPerWekk) + GetLeapDays(year - 1) - GetLeapDays(EpochYear - 1) + dayOfYear) % DaysPerWekk;
|
||||
long dayOfWeek = (EpochWeekDay + ((year - EpochYear) % DaysPerWeek) * (DaysPerNYear % DaysPerWeek) + GetLeapDays(year - 1) - GetLeapDays(EpochYear - 1) + dayOfYear) % DaysPerWeek;
|
||||
if (dayOfWeek < 0)
|
||||
{
|
||||
dayOfWeek += DaysPerWekk;
|
||||
dayOfWeek += DaysPerWeek;
|
||||
}
|
||||
|
||||
calendarAdditionalInfo.DayOfWeek = (uint)dayOfWeek;
|
||||
@@ -1328,7 +1329,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
calendarTime.Minute = (sbyte)(remainingSeconds / SecondsPerMinute);
|
||||
calendarTime.Second = (sbyte)(remainingSeconds % SecondsPerMinute);
|
||||
|
||||
int[] ip = MonthsLengths[IsLeap((int)year)];
|
||||
int[] ip = _monthsLengths[IsLeap((int)year)];
|
||||
|
||||
for (calendarTime.Month = 0; dayOfYear >= ip[calendarTime.Month]; ++calendarTime.Month)
|
||||
{
|
||||
@@ -1338,14 +1339,14 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
calendarTime.Day = (sbyte)(dayOfYear + 1);
|
||||
|
||||
calendarAdditionalInfo.IsDaySavingTime = false;
|
||||
calendarAdditionalInfo.GmtOffset = gmtOffset;
|
||||
calendarAdditionalInfo.GmtOffset = gmtOffset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static ResultCode ToCalendarTimeInternal(in TimeZoneRule rules, long time, out CalendarTimeInternal calendarTime, out CalendarAdditionalInfo calendarAdditionalInfo)
|
||||
{
|
||||
calendarTime = new CalendarTimeInternal();
|
||||
calendarTime = new CalendarTimeInternal();
|
||||
calendarAdditionalInfo = new CalendarAdditionalInfo();
|
||||
|
||||
ResultCode result;
|
||||
@@ -1368,7 +1369,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
seconds -= 1;
|
||||
|
||||
years = (seconds / SecondsPerRepeat + 1) * YearsPerRepeat;
|
||||
years = (seconds / SecondsPerRepeat + 1) * YearsPerRepeat;
|
||||
seconds = years * AverageSecondsPerYear;
|
||||
|
||||
if (time < rules.Ats[0])
|
||||
@@ -1411,7 +1412,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
}
|
||||
else
|
||||
{
|
||||
int low = 1;
|
||||
int low = 1;
|
||||
int high = rules.TimeCount;
|
||||
|
||||
while (low < high)
|
||||
@@ -1451,7 +1452,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
posixTime = 0;
|
||||
|
||||
int hour = calendarTime.Hour;
|
||||
int hour = calendarTime.Hour;
|
||||
int minute = calendarTime.Minute;
|
||||
|
||||
if (NormalizeOverflow32(ref hour, ref minute, MinutesPerHour))
|
||||
@@ -1467,10 +1468,10 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
return ResultCode.Overflow;
|
||||
}
|
||||
|
||||
calendarTime.Day = (sbyte)day;
|
||||
calendarTime.Day = (sbyte)day;
|
||||
calendarTime.Hour = (sbyte)hour;
|
||||
|
||||
long year = calendarTime.Year;
|
||||
long year = calendarTime.Year;
|
||||
long month = calendarTime.Month;
|
||||
|
||||
if (NormalizeOverflow64(ref year, ref month, MonthsPerYear))
|
||||
@@ -1499,7 +1500,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
li++;
|
||||
}
|
||||
|
||||
day += YearLengths[IsLeap((int)li)];
|
||||
day += _yearLengths[IsLeap((int)li)];
|
||||
}
|
||||
|
||||
while (day > DaysPerLYear)
|
||||
@@ -1511,7 +1512,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
li++;
|
||||
}
|
||||
|
||||
day -= YearLengths[IsLeap((int)li)];
|
||||
day -= _yearLengths[IsLeap((int)li)];
|
||||
|
||||
if (IncrementOverflow64(ref year, 1))
|
||||
{
|
||||
@@ -1521,7 +1522,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
while (true)
|
||||
{
|
||||
int i = MonthsLengths[IsLeap((int)year)][calendarTime.Month];
|
||||
int i = _monthsLengths[IsLeap((int)year)][calendarTime.Month];
|
||||
|
||||
if (day <= i)
|
||||
{
|
||||
@@ -1573,7 +1574,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
calendarTime.Second = 0;
|
||||
}
|
||||
|
||||
long low = long.MinValue;
|
||||
long low = long.MinValue;
|
||||
long high = long.MaxValue;
|
||||
|
||||
while (true)
|
||||
@@ -1670,15 +1671,15 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
Time = new CalendarTime()
|
||||
{
|
||||
Year = (short)calendarTime.Year,
|
||||
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,
|
||||
Day = calendarTime.Day,
|
||||
Hour = calendarTime.Hour,
|
||||
Minute = calendarTime.Minute,
|
||||
Second = calendarTime.Second
|
||||
Second = calendarTime.Second,
|
||||
},
|
||||
AdditionalInfo = calendarAdditionalInfo
|
||||
AdditionalInfo = calendarAdditionalInfo,
|
||||
};
|
||||
|
||||
return result;
|
||||
@@ -1686,18 +1687,18 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
internal static ResultCode ToPosixTime(in TimeZoneRule rules, CalendarTime calendarTime, out long posixTime)
|
||||
{
|
||||
CalendarTimeInternal calendarTimeInternal = new CalendarTimeInternal()
|
||||
CalendarTimeInternal calendarTimeInternal = new()
|
||||
{
|
||||
Year = calendarTime.Year,
|
||||
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,
|
||||
Month = (sbyte)(calendarTime.Month - 1),
|
||||
Day = calendarTime.Day,
|
||||
Hour = calendarTime.Hour,
|
||||
Minute = calendarTime.Minute,
|
||||
Second = calendarTime.Second
|
||||
Second = calendarTime.Second,
|
||||
};
|
||||
|
||||
return ToPosixTimeInternal(in rules, calendarTimeInternal, out posixTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ 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;
|
||||
@@ -24,11 +23,11 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
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 const 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 VirtualFileSystem _virtualFileSystem;
|
||||
private IntegrityCheckLevel _fsIntegrityCheckLevel;
|
||||
private ContentManager _contentManager;
|
||||
private ContentManager _contentManager;
|
||||
|
||||
public string[] LocationNameCache { get; private set; }
|
||||
|
||||
@@ -41,8 +40,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
public void InitializeInstance(VirtualFileSystem virtualFileSystem, ContentManager contentManager, IntegrityCheckLevel fsIntegrityCheckLevel)
|
||||
{
|
||||
_virtualFileSystem = virtualFileSystem;
|
||||
_contentManager = contentManager;
|
||||
_virtualFileSystem = virtualFileSystem;
|
||||
_contentManager = contentManager;
|
||||
_fsIntegrityCheckLevel = fsIntegrityCheckLevel;
|
||||
|
||||
InitializeLocationNameCache();
|
||||
@@ -90,31 +89,30 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
{
|
||||
if (HasTimeZoneBinaryTitle())
|
||||
{
|
||||
using (IStorage ncaFileStream = new LocalStorage(_virtualFileSystem.SwitchPathToSystemPath(GetTimeZoneBinaryTitleContentPath()), FileAccess.Read, FileMode.Open))
|
||||
using IStorage ncaFileStream = new LocalStorage(VirtualFileSystem.SwitchPathToSystemPath(GetTimeZoneBinaryTitleContentPath()), FileAccess.Read, FileMode.Open);
|
||||
|
||||
Nca nca = new(_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(binaryListFile.Get.AsStream());
|
||||
|
||||
List<string> locationNameList = new();
|
||||
|
||||
string locationName;
|
||||
while ((locationName = reader.ReadLine()) != null)
|
||||
{
|
||||
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();
|
||||
locationNameList.Add(locationName);
|
||||
}
|
||||
|
||||
LocationNameCache = locationNameList.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
LocationNameCache = new string[] { "UTC" };
|
||||
LocationNameCache = new[] { "UTC" };
|
||||
|
||||
Logger.Error?.Print(LogClass.ServiceTime, TimeZoneSystemTitleMissingErrorMessage);
|
||||
}
|
||||
@@ -129,9 +127,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
return new[] { (0, "UTC", "UTC") };
|
||||
}
|
||||
|
||||
List<(int Offset, string Location, string Abbr)> outList = new List<(int Offset, string Location, string Abbr)>();
|
||||
List<(int Offset, string Location, string Abbr)> outList = new();
|
||||
var now = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
using (IStorage ncaStorage = new LocalStorage(_virtualFileSystem.SwitchPathToSystemPath(tzBinaryContentPath), FileAccess.Read, FileMode.Open))
|
||||
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)
|
||||
@@ -149,7 +147,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
continue;
|
||||
}
|
||||
|
||||
TimeZoneRuleBox tzRuleBox = new TimeZoneRuleBox();
|
||||
TimeZoneRuleBox tzRuleBox = new();
|
||||
ref TimeZoneRule tzRule = ref tzRuleBox.Data;
|
||||
|
||||
TimeZone.ParseTimeZoneBinary(ref tzRule, tzif.Get.AsStream());
|
||||
@@ -219,7 +217,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
public ResultCode LoadLocationNameList(uint index, out string[] outLocationNameArray, uint maxLength)
|
||||
{
|
||||
List<string> locationNameList = new List<string>();
|
||||
List<string> locationNameList = new();
|
||||
|
||||
for (int i = 0; i < LocationNameCache.Length && i < maxLength; i++)
|
||||
{
|
||||
@@ -259,16 +257,16 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
internal ResultCode GetTimeZoneBinary(string locationName, out Stream timeZoneBinaryStream, out LocalStorage ncaFile)
|
||||
{
|
||||
timeZoneBinaryStream = null;
|
||||
ncaFile = null;
|
||||
ncaFile = null;
|
||||
|
||||
if (!HasTimeZoneBinaryTitle() || !IsLocationNameValid(locationName))
|
||||
{
|
||||
return ResultCode.TimeZoneNotFound;
|
||||
}
|
||||
|
||||
ncaFile = new LocalStorage(_virtualFileSystem.SwitchPathToSystemPath(GetTimeZoneBinaryTitleContentPath()), FileAccess.Read, FileMode.Open);
|
||||
ncaFile = new LocalStorage(VirtualFileSystem.SwitchPathToSystemPath(GetTimeZoneBinaryTitleContentPath()), FileAccess.Read, FileMode.Open);
|
||||
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile);
|
||||
Nca nca = new(_virtualFileSystem.KeySet, ncaFile);
|
||||
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _fsIntegrityCheckLevel);
|
||||
|
||||
using var timeZoneBinaryFile = new UniqueRef<IFile>();
|
||||
|
||||
@@ -7,20 +7,20 @@ 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 bool _isInitialized;
|
||||
private Box<TimeZoneRule> _myRules;
|
||||
private string _deviceLocationName;
|
||||
private UInt128 _timeZoneRuleVersion;
|
||||
private uint _totalLocationNameCount;
|
||||
private SteadyClockTimePoint _timeZoneUpdateTimePoint;
|
||||
private readonly object _lock = new();
|
||||
private readonly object _lock = new();
|
||||
|
||||
public TimeZoneManager()
|
||||
{
|
||||
_isInitialized = false;
|
||||
_deviceLocationName = "UTC";
|
||||
_isInitialized = false;
|
||||
_deviceLocationName = "UTC";
|
||||
_timeZoneRuleVersion = new UInt128();
|
||||
_myRules = new Box<TimeZoneRule>();
|
||||
_myRules = new Box<TimeZoneRule>();
|
||||
|
||||
_timeZoneUpdateTimePoint = SteadyClockTimePoint.GetRandom();
|
||||
}
|
||||
@@ -56,7 +56,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
if (_isInitialized)
|
||||
{
|
||||
deviceLocationName = _deviceLocationName;
|
||||
result = ResultCode.Success;
|
||||
result = ResultCode.Success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,15 +69,15 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
Box<TimeZoneRule> rules = new Box<TimeZoneRule>();
|
||||
Box<TimeZoneRule> rules = new();
|
||||
|
||||
bool timeZoneConversionSuccess = TimeZone.ParseTimeZoneBinary(ref rules.Data, timeZoneBinaryStream);
|
||||
|
||||
if (timeZoneConversionSuccess)
|
||||
{
|
||||
_deviceLocationName = locationName;
|
||||
_myRules = rules;
|
||||
result = ResultCode.Success;
|
||||
_myRules = rules;
|
||||
result = ResultCode.Success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
if (_isInitialized)
|
||||
{
|
||||
totalLocationNameCount = _totalLocationNameCount;
|
||||
result = ResultCode.Success;
|
||||
result = ResultCode.Success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
if (_isInitialized || bypassUninitialized)
|
||||
{
|
||||
_timeZoneUpdateTimePoint = timeZoneUpdatedTimePoint;
|
||||
result = ResultCode.Success;
|
||||
result = ResultCode.Success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,12 +135,12 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
if (_isInitialized)
|
||||
{
|
||||
timeZoneUpdatedTimePoint = _timeZoneUpdateTimePoint;
|
||||
result = ResultCode.Success;
|
||||
result = ResultCode.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeZoneUpdatedTimePoint = SteadyClockTimePoint.GetRandom();
|
||||
result = ResultCode.UninitializedClock;
|
||||
result = ResultCode.UninitializedClock;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,12 +181,12 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
if (_isInitialized)
|
||||
{
|
||||
timeZoneRuleVersion = _timeZoneRuleVersion;
|
||||
result = ResultCode.Success;
|
||||
result = ResultCode.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeZoneRuleVersion = new UInt128();
|
||||
result = ResultCode.UninitializedClock;
|
||||
result = ResultCode.UninitializedClock;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
else
|
||||
{
|
||||
calendar = new CalendarInfo();
|
||||
result = ResultCode.UninitializedClock;
|
||||
result = ResultCode.UninitializedClock;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
else
|
||||
{
|
||||
posixTime = 0;
|
||||
result = ResultCode.UninitializedClock;
|
||||
result = ResultCode.UninitializedClock;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,4 +18,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
public int GmtOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 0x4, Size = 0x20, CharSet = CharSet.Ansi)]
|
||||
struct CalendarInfo
|
||||
{
|
||||
public CalendarTime Time;
|
||||
public CalendarTime Time;
|
||||
public CalendarAdditionalInfo AdditionalInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,4 +12,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
public sbyte Minute;
|
||||
public sbyte Second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,4 +25,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
public ushort Padding2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,4 +53,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
|
||||
public int DefaultType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,4 +16,4 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
public int TypeCount;
|
||||
public int CharCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.Types
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct SteadyClockContext
|
||||
{
|
||||
public ulong InternalOffset;
|
||||
public ulong InternalOffset;
|
||||
public UInt128 ClockSourceId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,18 @@ namespace Ryujinx.HLE.HOS.Services.Time
|
||||
[Flags]
|
||||
enum TimePermissions
|
||||
{
|
||||
LocalSystemClockWritableMask = 0x1,
|
||||
UserSystemClockWritableMask = 0x2,
|
||||
LocalSystemClockWritableMask = 0x1,
|
||||
UserSystemClockWritableMask = 0x2,
|
||||
NetworkSystemClockWritableMask = 0x4,
|
||||
TimeZoneWritableMask = 0x8,
|
||||
SteadyClockWritableMask = 0x10,
|
||||
BypassUninitialized = 0x20,
|
||||
TimeZoneWritableMask = 0x8,
|
||||
SteadyClockWritableMask = 0x10,
|
||||
BypassUninitialized = 0x20,
|
||||
|
||||
User = 0,
|
||||
Admin = LocalSystemClockWritableMask | UserSystemClockWritableMask | TimeZoneWritableMask,
|
||||
System = NetworkSystemClockWritableMask,
|
||||
User = 0,
|
||||
Admin = LocalSystemClockWritableMask | UserSystemClockWritableMask | TimeZoneWritableMask,
|
||||
System = NetworkSystemClockWritableMask,
|
||||
SystemUpdate = BypassUninitialized,
|
||||
Repair = SteadyClockWritableMask,
|
||||
Manufacture = LocalSystemClockWritableMask | UserSystemClockWritableMask | NetworkSystemClockWritableMask | TimeZoneWritableMask | SteadyClockWritableMask
|
||||
Repair = SteadyClockWritableMask,
|
||||
Manufacture = LocalSystemClockWritableMask | UserSystemClockWritableMask | NetworkSystemClockWritableMask | TimeZoneWritableMask | SteadyClockWritableMask,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user