Просмотр исходного кода

Some things for time:* (#211)

- Fully implement ISystemClock
- Implement ISteadyClock 1.0 cmds
- Add cmd 300 to IStaticService
- Add EphemeralNetwork to SystemClockType
Thomas Guillemard 7 лет назад
Родитель
Сommit
0c96e22d40

+ 19 - 5
Ryujinx.HLE/OsHle/Services/Time/IStaticService.cs

@@ -1,4 +1,5 @@
 using Ryujinx.HLE.OsHle.Ipc;
+using System;
 using System.Collections.Generic;
 
 namespace Ryujinx.HLE.OsHle.Services.Time
@@ -9,15 +10,18 @@ namespace Ryujinx.HLE.OsHle.Services.Time
 
         public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
 
+        private static readonly DateTime StartupDate = DateTime.UtcNow;
+
         public IStaticService()
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                { 0, GetStandardUserSystemClock    },
-                { 1, GetStandardNetworkSystemClock },
-                { 2, GetStandardSteadyClock        },
-                { 3, GetTimeZoneService            },
-                { 4, GetStandardLocalSystemClock   }
+                { 0,   GetStandardUserSystemClock                 },
+                { 1,   GetStandardNetworkSystemClock              },
+                { 2,   GetStandardSteadyClock                     },
+                { 3,   GetTimeZoneService                         },
+                { 4,   GetStandardLocalSystemClock                },
+                { 300, CalculateMonotonicSystemClockBaseTimePoint }
             };
         }
 
@@ -56,5 +60,15 @@ namespace Ryujinx.HLE.OsHle.Services.Time
             return 0;
         }
 
+        public long CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx Context)
+        {
+            long TimeOffset              = (long)(DateTime.UtcNow - StartupDate).TotalSeconds;
+            long SystemClockContextEpoch = Context.RequestData.ReadInt64();
+
+            Context.ResponseData.Write(TimeOffset + SystemClockContextEpoch);
+
+            return 0;
+        }
+
     }
 }

+ 34 - 1
Ryujinx.HLE/OsHle/Services/Time/ISteadyClock.cs

@@ -1,4 +1,5 @@
 using Ryujinx.HLE.OsHle.Ipc;
+using System;
 using System.Collections.Generic;
 
 namespace Ryujinx.HLE.OsHle.Services.Time
@@ -9,12 +10,44 @@ namespace Ryujinx.HLE.OsHle.Services.Time
 
         public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
 
+        private ulong TestOffset;
+
         public ISteadyClock()
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                //...
+                { 0, GetCurrentTimePoint },
+                { 1, GetTestOffset       },
+                { 2, SetTestOffset       }
             };
+
+            TestOffset = 0;
+        }
+
+        public long GetCurrentTimePoint(ServiceCtx Context)
+        {
+            Context.ResponseData.Write((long)(System.Diagnostics.Process.GetCurrentProcess().StartTime - DateTime.Now).TotalSeconds);
+
+            for (int i = 0; i < 0x10; i++)
+            {
+                Context.ResponseData.Write((byte)0);
+            }
+
+            return 0;
+        }
+
+        public long GetTestOffset(ServiceCtx Context)
+        {
+            Context.ResponseData.Write(TestOffset);
+
+            return 0;
+        }
+
+        public long SetTestOffset(ServiceCtx Context)
+        {
+            TestOffset = Context.RequestData.ReadUInt64();
+
+            return 0;
         }
     }
 }

+ 68 - 3
Ryujinx.HLE/OsHle/Services/Time/ISystemClock.cs

@@ -14,14 +14,36 @@ namespace Ryujinx.HLE.OsHle.Services.Time
 
         private SystemClockType ClockType;
 
+        private DateTime SystemClockContextEpoch;
+
+        private long SystemClockTimePoint;
+
+        private byte[] SystemClockContextEnding;
+
+        private long TimeOffset;
+
         public ISystemClock(SystemClockType ClockType)
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                { 0, GetCurrentTime }
+                { 0, GetCurrentTime        },
+                { 1, SetCurrentTime        },
+                { 2, GetSystemClockContext },
+                { 3, SetSystemClockContext }
             };
 
-            this.ClockType = ClockType;
+            this.ClockType           = ClockType;
+            SystemClockContextEpoch  = System.Diagnostics.Process.GetCurrentProcess().StartTime;
+            SystemClockContextEnding = new byte[0x10];
+            TimeOffset               = 0;
+
+            if (ClockType == SystemClockType.User ||
+                ClockType == SystemClockType.Network)
+            {
+                SystemClockContextEpoch = SystemClockContextEpoch.ToUniversalTime();
+            }
+
+            SystemClockTimePoint = (long)(SystemClockContextEpoch - Epoch).TotalSeconds;
         }
 
         public long GetCurrentTime(ServiceCtx Context)
@@ -34,7 +56,50 @@ namespace Ryujinx.HLE.OsHle.Services.Time
                 CurrentTime = CurrentTime.ToUniversalTime();
             }
 
-            Context.ResponseData.Write((long)(DateTime.Now - Epoch).TotalSeconds);
+            Context.ResponseData.Write((long)((CurrentTime - Epoch).TotalSeconds) + TimeOffset);
+
+            return 0;
+        }
+
+        public long SetCurrentTime(ServiceCtx Context)
+        {
+            DateTime CurrentTime = DateTime.Now;
+
+            if (ClockType == SystemClockType.User ||
+                ClockType == SystemClockType.Network)
+            {
+                CurrentTime = CurrentTime.ToUniversalTime();
+            }
+
+            TimeOffset = (Context.RequestData.ReadInt64() - (long)(CurrentTime - Epoch).TotalSeconds);
+
+            return 0;
+        }
+
+        public long GetSystemClockContext(ServiceCtx Context)
+        {
+            Context.ResponseData.Write((long)(SystemClockContextEpoch - Epoch).TotalSeconds);
+
+            // The point in time, TODO: is there a link between epoch and this?
+            Context.ResponseData.Write(SystemClockTimePoint);
+
+            // This seems to be some kind of identifier?
+            for (int i = 0; i < 0x10; i++)
+            {
+                Context.ResponseData.Write(SystemClockContextEnding[i]);
+            }
+
+            return 0;
+        }
+
+        public long SetSystemClockContext(ServiceCtx Context)
+        {
+            long NewSystemClockEpoch     = Context.RequestData.ReadInt64();
+            long NewSystemClockTimePoint = Context.RequestData.ReadInt64();
+
+            SystemClockContextEpoch      = Epoch.Add(TimeSpan.FromSeconds(NewSystemClockEpoch));
+            SystemClockTimePoint         = NewSystemClockTimePoint;
+            SystemClockContextEnding     = Context.RequestData.ReadBytes(0x10);
 
             return 0;
         }

+ 2 - 1
Ryujinx.HLE/OsHle/Services/Time/SystemClockType.cs

@@ -4,6 +4,7 @@ namespace Ryujinx.HLE.OsHle.Services.Time
     {
         User,
         Network,
-        Local
+        Local,
+        EphemeralNetwork
     }
 }