From a22c5a388065997211090e97c34d7320699e4a00 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Thu, 11 May 2023 21:05:27 -0400
Subject: [PATCH] time: implement ContinuousAdjustmentTimePoint

---
 src/core/hle/service/time/clock_types.h       | 12 ++++++++++++
 .../hle/service/time/time_sharedmemory.cpp    | 19 +++++++++++++++++++
 src/core/hle/service/time/time_sharedmemory.h |  5 +++--
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/service/time/clock_types.h b/src/core/hle/service/time/clock_types.h
index ed1eb5b2d4..e6293ffb9b 100644
--- a/src/core/hle/service/time/clock_types.h
+++ b/src/core/hle/service/time/clock_types.h
@@ -59,6 +59,18 @@ static_assert(sizeof(SystemClockContext) == 0x20, "SystemClockContext is incorre
 static_assert(std::is_trivially_copyable_v<SystemClockContext>,
               "SystemClockContext must be trivially copyable");
 
+struct ContinuousAdjustmentTimePoint {
+    s64 measurement_offset;
+    s64 diff_scale;
+    u32 shift_amount;
+    s64 lower;
+    s64 upper;
+    Common::UUID clock_source_id;
+};
+static_assert(sizeof(ContinuousAdjustmentTimePoint) == 0x38);
+static_assert(std::is_trivially_copyable_v<ContinuousAdjustmentTimePoint>,
+              "ContinuousAdjustmentTimePoint must be trivially copyable");
+
 /// https://switchbrew.org/wiki/Glue_services#TimeSpanType
 struct TimeSpanType {
     s64 nanoseconds{};
diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp
index ff53a7d6f7..ce1c85bcc5 100644
--- a/src/core/hle/service/time/time_sharedmemory.cpp
+++ b/src/core/hle/service/time/time_sharedmemory.cpp
@@ -30,6 +30,25 @@ void SharedMemory::SetupStandardSteadyClock(const Common::UUID& clock_source_id,
 }
 
 void SharedMemory::UpdateLocalSystemClockContext(const Clock::SystemClockContext& context) {
+    // lower and upper are related to the measurement point for the steady time point,
+    // and compare equal on boot
+    const s64 time_point_ns = context.steady_time_point.time_point * 1'000'000'000LL;
+
+    // This adjusts for some sort of time skew
+    // Both 0 on boot
+    const s64 diff_scale = 0;
+    const u32 shift_amount = 0;
+
+    const Clock::ContinuousAdjustmentTimePoint adjustment{
+        .measurement_offset = system.CoreTiming().GetGlobalTimeNs().count(),
+        .diff_scale = diff_scale,
+        .shift_amount = shift_amount,
+        .lower = time_point_ns,
+        .upper = time_point_ns,
+        .clock_source_id = context.steady_time_point.clock_source_id,
+    };
+
+    StoreToLockFreeAtomicType(&GetFormat()->continuous_adjustment_timepoint, adjustment);
     StoreToLockFreeAtomicType(&GetFormat()->standard_local_system_clock_context, context);
 }
 
diff --git a/src/core/hle/service/time/time_sharedmemory.h b/src/core/hle/service/time/time_sharedmemory.h
index 044a4d24ec..c89be97651 100644
--- a/src/core/hle/service/time/time_sharedmemory.h
+++ b/src/core/hle/service/time/time_sharedmemory.h
@@ -65,14 +65,15 @@ public:
         LockFreeAtomicType<Clock::SystemClockContext> standard_local_system_clock_context;
         LockFreeAtomicType<Clock::SystemClockContext> standard_network_system_clock_context;
         LockFreeAtomicType<bool> is_standard_user_system_clock_automatic_correction_enabled;
-        u32 format_version;
+        LockFreeAtomicType<Clock::ContinuousAdjustmentTimePoint> continuous_adjustment_timepoint;
     };
     static_assert(offsetof(Format, standard_steady_clock_timepoint) == 0x0);
     static_assert(offsetof(Format, standard_local_system_clock_context) == 0x38);
     static_assert(offsetof(Format, standard_network_system_clock_context) == 0x80);
     static_assert(offsetof(Format, is_standard_user_system_clock_automatic_correction_enabled) ==
                   0xc8);
-    static_assert(sizeof(Format) == 0xd8, "Format is an invalid size");
+    static_assert(offsetof(Format, continuous_adjustment_timepoint) == 0xd0);
+    static_assert(sizeof(Format) == 0x148, "Format is an invalid size");
 
     void SetupStandardSteadyClock(const Common::UUID& clock_source_id,
                                   Clock::TimeSpanType current_time_point);