early-access version 4075
This commit is contained in:
		| @@ -1,7 +1,7 @@ | ||||
| yuzu emulator early access | ||||
| ============= | ||||
|  | ||||
| This is the source code for early-access 4074. | ||||
| This is the source code for early-access 4075. | ||||
|  | ||||
| ## Legal Notice | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								externals/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								externals/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -178,6 +178,9 @@ if (NOT TARGET stb::headers) | ||||
|     add_library(stb::headers ALIAS stb) | ||||
| endif() | ||||
|  | ||||
| add_library(tz tz/tz/tz.cpp) | ||||
| target_include_directories(tz PUBLIC ./tz) | ||||
|  | ||||
| add_library(bc_decoder bc_decoder/bc_decoder.cpp) | ||||
| target_include_directories(bc_decoder PUBLIC ./bc_decoder) | ||||
|  | ||||
|   | ||||
| @@ -29,28 +29,32 @@ NativeClock::NativeClock() { | ||||
|     gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq); | ||||
| } | ||||
|  | ||||
| void NativeClock::Reset() { | ||||
|     start_ticks = GetUptime(); | ||||
| } | ||||
|  | ||||
| std::chrono::nanoseconds NativeClock::GetTimeNS() const { | ||||
|     return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_cntfrq_factor)}; | ||||
|     return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)}; | ||||
| } | ||||
|  | ||||
| std::chrono::microseconds NativeClock::GetTimeUS() const { | ||||
|     return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_cntfrq_factor)}; | ||||
|     return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_cntfrq_factor)}; | ||||
| } | ||||
|  | ||||
| std::chrono::milliseconds NativeClock::GetTimeMS() const { | ||||
|     return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_cntfrq_factor)}; | ||||
|     return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_cntfrq_factor)}; | ||||
| } | ||||
|  | ||||
| u64 NativeClock::GetCNTPCT() const { | ||||
|     return MultiplyHigh(GetHostTicksElapsed(), guest_cntfrq_factor); | ||||
| s64 NativeClock::GetCNTPCT() const { | ||||
|     return MultiplyHigh(GetUptime() - start_ticks, guest_cntfrq_factor); | ||||
| } | ||||
|  | ||||
| u64 NativeClock::GetGPUTick() const { | ||||
|     return MultiplyHigh(GetHostTicksElapsed(), gputick_cntfrq_factor); | ||||
| s64 NativeClock::GetGPUTick() const { | ||||
|     return MultiplyHigh(GetUptime() - start_ticks, gputick_cntfrq_factor); | ||||
| } | ||||
|  | ||||
| u64 NativeClock::GetHostTicksNow() const { | ||||
|     u64 cntvct_el0 = 0; | ||||
| s64 NativeClock::GetUptime() const { | ||||
|     s64 cntvct_el0 = 0; | ||||
|     asm volatile("dsb ish\n\t" | ||||
|                  "mrs %[cntvct_el0], cntvct_el0\n\t" | ||||
|                  "dsb ish\n\t" | ||||
| @@ -58,15 +62,11 @@ u64 NativeClock::GetHostTicksNow() const { | ||||
|     return cntvct_el0; | ||||
| } | ||||
|  | ||||
| u64 NativeClock::GetHostTicksElapsed() const { | ||||
|     return GetHostTicksNow(); | ||||
| } | ||||
|  | ||||
| bool NativeClock::IsNative() const { | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| u64 NativeClock::GetHostCNTFRQ() { | ||||
| s64 NativeClock::GetHostCNTFRQ() { | ||||
|     u64 cntfrq_el0 = 0; | ||||
|     std::string_view board{""}; | ||||
| #ifdef ANDROID | ||||
|   | ||||
| @@ -11,23 +11,23 @@ class NativeClock final : public WallClock { | ||||
| public: | ||||
|     explicit NativeClock(); | ||||
|  | ||||
|     void Reset() override; | ||||
|  | ||||
|     std::chrono::nanoseconds GetTimeNS() const override; | ||||
|  | ||||
|     std::chrono::microseconds GetTimeUS() const override; | ||||
|  | ||||
|     std::chrono::milliseconds GetTimeMS() const override; | ||||
|  | ||||
|     u64 GetCNTPCT() const override; | ||||
|     s64 GetCNTPCT() const override; | ||||
|  | ||||
|     u64 GetGPUTick() const override; | ||||
|     s64 GetGPUTick() const override; | ||||
|  | ||||
|     u64 GetHostTicksNow() const override; | ||||
|  | ||||
|     u64 GetHostTicksElapsed() const override; | ||||
|     s64 GetUptime() const override; | ||||
|  | ||||
|     bool IsNative() const override; | ||||
|  | ||||
|     static u64 GetHostCNTFRQ(); | ||||
|     static s64 GetHostCNTFRQ(); | ||||
|  | ||||
| public: | ||||
|     using FactorType = unsigned __int128; | ||||
| @@ -42,6 +42,7 @@ private: | ||||
|     FactorType ms_cntfrq_factor; | ||||
|     FactorType guest_cntfrq_factor; | ||||
|     FactorType gputick_cntfrq_factor; | ||||
|     s64 start_ticks; | ||||
| }; | ||||
|  | ||||
| } // namespace Common::Arm64 | ||||
|   | ||||
| @@ -18,4 +18,4 @@ struct MemoryInfo { | ||||
|  */ | ||||
| [[nodiscard]] const MemoryInfo& GetMemInfo(); | ||||
|  | ||||
| } // namespace Common | ||||
| } // namespace Common | ||||
|   | ||||
| @@ -419,7 +419,9 @@ struct Values { | ||||
|         linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true}; | ||||
|     SwitchableSetting<s64> custom_rtc{ | ||||
|         linkage, 0,    "custom_rtc",       Category::System, Specialization::Time, | ||||
|         true,    true, &custom_rtc_enabled}; | ||||
|         false,   true, &custom_rtc_enabled}; | ||||
|     SwitchableSetting<s64, false> custom_rtc_offset{ | ||||
|         linkage, 0, "custom_rtc_offset", Category::System, Specialization::Countable, true, true}; | ||||
|     // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` | ||||
|     s64 custom_rtc_differential; | ||||
|     SwitchableSetting<bool> rng_seed_enabled{ | ||||
|   | ||||
| @@ -12,9 +12,8 @@ | ||||
| namespace Common { | ||||
|  | ||||
| struct UUID { | ||||
|     std::array<u8, 0x10> uuid{}; | ||||
|     std::array<u8, 0x10> uuid; | ||||
|  | ||||
|     /// Constructs an invalid UUID. | ||||
|     constexpr UUID() = default; | ||||
|  | ||||
|     /// Constructs a UUID from a reference to a 128 bit array. | ||||
| @@ -34,14 +33,6 @@ struct UUID { | ||||
|      */ | ||||
|     explicit UUID(std::string_view uuid_string); | ||||
|  | ||||
|     ~UUID() = default; | ||||
|  | ||||
|     constexpr UUID(const UUID&) noexcept = default; | ||||
|     constexpr UUID(UUID&&) noexcept = default; | ||||
|  | ||||
|     constexpr UUID& operator=(const UUID&) noexcept = default; | ||||
|     constexpr UUID& operator=(UUID&&) noexcept = default; | ||||
|  | ||||
|     /** | ||||
|      * Returns whether the stored UUID is valid or not. | ||||
|      * | ||||
| @@ -121,6 +112,7 @@ struct UUID { | ||||
|     friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default; | ||||
| }; | ||||
| static_assert(sizeof(UUID) == 0x10, "UUID has incorrect size."); | ||||
| static_assert(std::is_trivial_v<UUID>); | ||||
|  | ||||
| /// An invalid UUID. This UUID has all its bytes set to 0. | ||||
| constexpr UUID InvalidUUID = {}; | ||||
|   | ||||
| @@ -18,34 +18,39 @@ namespace Common { | ||||
|  | ||||
| class StandardWallClock final : public WallClock { | ||||
| public: | ||||
|     explicit StandardWallClock() : start_time{SteadyClock::Now()} {} | ||||
|     explicit StandardWallClock() {} | ||||
|  | ||||
|     void Reset() override { | ||||
|         start_time = std::chrono::system_clock::now(); | ||||
|     } | ||||
|  | ||||
|     std::chrono::nanoseconds GetTimeNS() const override { | ||||
|         return SteadyClock::Now() - start_time; | ||||
|         return std::chrono::duration_cast<std::chrono::nanoseconds>( | ||||
|             std::chrono::system_clock::now().time_since_epoch()); | ||||
|     } | ||||
|  | ||||
|     std::chrono::microseconds GetTimeUS() const override { | ||||
|         return static_cast<std::chrono::microseconds>(GetHostTicksElapsed() / NsToUsRatio::den); | ||||
|         return std::chrono::duration_cast<std::chrono::microseconds>( | ||||
|             std::chrono::system_clock::now().time_since_epoch()); | ||||
|     } | ||||
|  | ||||
|     std::chrono::milliseconds GetTimeMS() const override { | ||||
|         return static_cast<std::chrono::milliseconds>(GetHostTicksElapsed() / NsToMsRatio::den); | ||||
|         return std::chrono::duration_cast<std::chrono::milliseconds>( | ||||
|             std::chrono::system_clock::now().time_since_epoch()); | ||||
|     } | ||||
|  | ||||
|     u64 GetCNTPCT() const override { | ||||
|         return GetHostTicksElapsed() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; | ||||
|     s64 GetCNTPCT() const override { | ||||
|         return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; | ||||
|     } | ||||
|  | ||||
|     u64 GetGPUTick() const override { | ||||
|         return GetHostTicksElapsed() * NsToGPUTickRatio::num / NsToGPUTickRatio::den; | ||||
|     s64 GetGPUTick() const override { | ||||
|         return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den; | ||||
|     } | ||||
|  | ||||
|     u64 GetHostTicksNow() const override { | ||||
|         return static_cast<u64>(SteadyClock::Now().time_since_epoch().count()); | ||||
|     } | ||||
|  | ||||
|     u64 GetHostTicksElapsed() const override { | ||||
|         return static_cast<u64>(GetTimeNS().count()); | ||||
|     s64 GetUptime() const override { | ||||
|         return std::chrono::duration_cast<std::chrono::nanoseconds>( | ||||
|                    std::chrono::system_clock::now() - start_time) | ||||
|             .count(); | ||||
|     } | ||||
|  | ||||
|     bool IsNative() const override { | ||||
| @@ -53,7 +58,7 @@ public: | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     SteadyClock::time_point start_time; | ||||
|     std::chrono::system_clock::time_point start_time{}; | ||||
| }; | ||||
|  | ||||
| std::unique_ptr<WallClock> CreateOptimalClock() { | ||||
|   | ||||
| @@ -19,6 +19,8 @@ public: | ||||
|  | ||||
|     virtual ~WallClock() = default; | ||||
|  | ||||
|     virtual void Reset() = 0; | ||||
|  | ||||
|     /// @returns The time in nanoseconds since the construction of this clock. | ||||
|     virtual std::chrono::nanoseconds GetTimeNS() const = 0; | ||||
|  | ||||
| @@ -29,16 +31,13 @@ public: | ||||
|     virtual std::chrono::milliseconds GetTimeMS() const = 0; | ||||
|  | ||||
|     /// @returns The guest CNTPCT ticks since the construction of this clock. | ||||
|     virtual u64 GetCNTPCT() const = 0; | ||||
|     virtual s64 GetCNTPCT() const = 0; | ||||
|  | ||||
|     /// @returns The guest GPU ticks since the construction of this clock. | ||||
|     virtual u64 GetGPUTick() const = 0; | ||||
|     virtual s64 GetGPUTick() const = 0; | ||||
|  | ||||
|     /// @returns The raw host timer ticks since an indeterminate epoch. | ||||
|     virtual u64 GetHostTicksNow() const = 0; | ||||
|  | ||||
|     /// @returns The raw host timer ticks since the construction of this clock. | ||||
|     virtual u64 GetHostTicksElapsed() const = 0; | ||||
|     virtual s64 GetUptime() const = 0; | ||||
|  | ||||
|     /// @returns Whether the clock directly uses the host's hardware clock. | ||||
|     virtual bool IsNative() const = 0; | ||||
|   | ||||
| @@ -8,39 +8,39 @@ | ||||
| namespace Common::X64 { | ||||
|  | ||||
| NativeClock::NativeClock(u64 rdtsc_frequency_) | ||||
|     : start_ticks{FencedRDTSC()}, rdtsc_frequency{rdtsc_frequency_}, | ||||
|       ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency)}, | ||||
|     : rdtsc_frequency{rdtsc_frequency_}, ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, | ||||
|                                                                                rdtsc_frequency)}, | ||||
|       us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency)}, | ||||
|       ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency)}, | ||||
|       cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)}, | ||||
|       gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {} | ||||
|  | ||||
| void NativeClock::Reset() { | ||||
|     start_ticks = FencedRDTSC(); | ||||
| } | ||||
|  | ||||
| std::chrono::nanoseconds NativeClock::GetTimeNS() const { | ||||
|     return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_rdtsc_factor)}; | ||||
|     return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)}; | ||||
| } | ||||
|  | ||||
| std::chrono::microseconds NativeClock::GetTimeUS() const { | ||||
|     return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_rdtsc_factor)}; | ||||
|     return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_rdtsc_factor)}; | ||||
| } | ||||
|  | ||||
| std::chrono::milliseconds NativeClock::GetTimeMS() const { | ||||
|     return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_rdtsc_factor)}; | ||||
|     return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_rdtsc_factor)}; | ||||
| } | ||||
|  | ||||
| u64 NativeClock::GetCNTPCT() const { | ||||
|     return MultiplyHigh(GetHostTicksElapsed(), cntpct_rdtsc_factor); | ||||
| s64 NativeClock::GetCNTPCT() const { | ||||
|     return MultiplyHigh(GetUptime() - start_ticks, cntpct_rdtsc_factor); | ||||
| } | ||||
|  | ||||
| u64 NativeClock::GetGPUTick() const { | ||||
|     return MultiplyHigh(GetHostTicksElapsed(), gputick_rdtsc_factor); | ||||
| s64 NativeClock::GetGPUTick() const { | ||||
|     return MultiplyHigh(GetUptime() - start_ticks, gputick_rdtsc_factor); | ||||
| } | ||||
|  | ||||
| u64 NativeClock::GetHostTicksNow() const { | ||||
|     return FencedRDTSC(); | ||||
| } | ||||
|  | ||||
| u64 NativeClock::GetHostTicksElapsed() const { | ||||
|     return FencedRDTSC() - start_ticks; | ||||
| s64 NativeClock::GetUptime() const { | ||||
|     return static_cast<s64>(FencedRDTSC()); | ||||
| } | ||||
|  | ||||
| bool NativeClock::IsNative() const { | ||||
|   | ||||
| @@ -11,19 +11,19 @@ class NativeClock final : public WallClock { | ||||
| public: | ||||
|     explicit NativeClock(u64 rdtsc_frequency_); | ||||
|  | ||||
|     void Reset() override; | ||||
|  | ||||
|     std::chrono::nanoseconds GetTimeNS() const override; | ||||
|  | ||||
|     std::chrono::microseconds GetTimeUS() const override; | ||||
|  | ||||
|     std::chrono::milliseconds GetTimeMS() const override; | ||||
|  | ||||
|     u64 GetCNTPCT() const override; | ||||
|     s64 GetCNTPCT() const override; | ||||
|  | ||||
|     u64 GetGPUTick() const override; | ||||
|     s64 GetGPUTick() const override; | ||||
|  | ||||
|     u64 GetHostTicksNow() const override; | ||||
|  | ||||
|     u64 GetHostTicksElapsed() const override; | ||||
|     s64 GetUptime() const override; | ||||
|  | ||||
|     bool IsNative() const override; | ||||
|  | ||||
|   | ||||
| @@ -515,6 +515,24 @@ add_library(core STATIC | ||||
|     hle/service/glue/glue_manager.h | ||||
|     hle/service/glue/notif.cpp | ||||
|     hle/service/glue/notif.h | ||||
|     hle/service/glue/time/alarm_worker.cpp | ||||
|     hle/service/glue/time/alarm_worker.h | ||||
|     hle/service/glue/time/file_timestamp_worker.cpp | ||||
|     hle/service/glue/time/file_timestamp_worker.h | ||||
|     hle/service/glue/time/manager.cpp | ||||
|     hle/service/glue/time/manager.h | ||||
|     hle/service/glue/time/pm_state_change_handler.cpp | ||||
|     hle/service/glue/time/pm_state_change_handler.h | ||||
|     hle/service/glue/time/standard_steady_clock_resource.cpp | ||||
|     hle/service/glue/time/standard_steady_clock_resource.h | ||||
|     hle/service/glue/time/static.cpp | ||||
|     hle/service/glue/time/static.h | ||||
|     hle/service/glue/time/time_zone.cpp | ||||
|     hle/service/glue/time/time_zone.h | ||||
|     hle/service/glue/time/time_zone_binary.cpp | ||||
|     hle/service/glue/time/time_zone_binary.h | ||||
|     hle/service/glue/time/worker.cpp | ||||
|     hle/service/glue/time/worker.h | ||||
|     hle/service/grc/grc.cpp | ||||
|     hle/service/grc/grc.h | ||||
|     hle/service/hid/hid.cpp | ||||
| @@ -693,6 +711,46 @@ add_library(core STATIC | ||||
|     hle/service/prepo/prepo.h | ||||
|     hle/service/psc/psc.cpp | ||||
|     hle/service/psc/psc.h | ||||
|     hle/service/psc/time/alarms.cpp | ||||
|     hle/service/psc/time/alarms.h | ||||
|     hle/service/psc/time/clocks/context_writers.cpp | ||||
|     hle/service/psc/time/clocks/context_writers.h | ||||
|     hle/service/psc/time/clocks/ephemeral_network_system_clock_core.h | ||||
|     hle/service/psc/time/clocks/standard_local_system_clock_core.cpp | ||||
|     hle/service/psc/time/clocks/standard_local_system_clock_core.h | ||||
|     hle/service/psc/time/clocks/standard_network_system_clock_core.cpp | ||||
|     hle/service/psc/time/clocks/standard_network_system_clock_core.h | ||||
|     hle/service/psc/time/clocks/standard_steady_clock_core.cpp | ||||
|     hle/service/psc/time/clocks/standard_steady_clock_core.h | ||||
|     hle/service/psc/time/clocks/standard_user_system_clock_core.cpp | ||||
|     hle/service/psc/time/clocks/standard_user_system_clock_core.h | ||||
|     hle/service/psc/time/clocks/steady_clock_core.h | ||||
|     hle/service/psc/time/clocks/system_clock_core.cpp | ||||
|     hle/service/psc/time/clocks/system_clock_core.h | ||||
|     hle/service/psc/time/clocks/tick_based_steady_clock_core.cpp | ||||
|     hle/service/psc/time/clocks/tick_based_steady_clock_core.h | ||||
|     hle/service/psc/time/common.cpp | ||||
|     hle/service/psc/time/common.h | ||||
|     hle/service/psc/time/errors.h | ||||
|     hle/service/psc/time/shared_memory.cpp | ||||
|     hle/service/psc/time/shared_memory.h | ||||
|     hle/service/psc/time/static.cpp | ||||
|     hle/service/psc/time/static.h | ||||
|     hle/service/psc/time/manager.h | ||||
|     hle/service/psc/time/power_state_service.cpp | ||||
|     hle/service/psc/time/power_state_service.h | ||||
|     hle/service/psc/time/service_manager.cpp | ||||
|     hle/service/psc/time/service_manager.h | ||||
|     hle/service/psc/time/steady_clock.cpp | ||||
|     hle/service/psc/time/steady_clock.h | ||||
|     hle/service/psc/time/system_clock.cpp | ||||
|     hle/service/psc/time/system_clock.h | ||||
|     hle/service/psc/time/time_zone.cpp | ||||
|     hle/service/psc/time/time_zone.h | ||||
|     hle/service/psc/time/time_zone_service.cpp | ||||
|     hle/service/psc/time/time_zone_service.h | ||||
|     hle/service/psc/time/power_state_request_manager.cpp | ||||
|     hle/service/psc/time/power_state_request_manager.h | ||||
|     hle/service/ptm/psm.cpp | ||||
|     hle/service/ptm/psm.h | ||||
|     hle/service/ptm/ptm.cpp | ||||
| @@ -760,40 +818,6 @@ add_library(core STATIC | ||||
|     hle/service/ssl/ssl.cpp | ||||
|     hle/service/ssl/ssl.h | ||||
|     hle/service/ssl/ssl_backend.h | ||||
|     hle/service/time/clock_types.h | ||||
|     hle/service/time/ephemeral_network_system_clock_context_writer.h | ||||
|     hle/service/time/ephemeral_network_system_clock_core.h | ||||
|     hle/service/time/errors.h | ||||
|     hle/service/time/local_system_clock_context_writer.h | ||||
|     hle/service/time/network_system_clock_context_writer.h | ||||
|     hle/service/time/standard_local_system_clock_core.h | ||||
|     hle/service/time/standard_network_system_clock_core.h | ||||
|     hle/service/time/standard_steady_clock_core.cpp | ||||
|     hle/service/time/standard_steady_clock_core.h | ||||
|     hle/service/time/standard_user_system_clock_core.cpp | ||||
|     hle/service/time/standard_user_system_clock_core.h | ||||
|     hle/service/time/steady_clock_core.h | ||||
|     hle/service/time/system_clock_context_update_callback.cpp | ||||
|     hle/service/time/system_clock_context_update_callback.h | ||||
|     hle/service/time/system_clock_core.cpp | ||||
|     hle/service/time/system_clock_core.h | ||||
|     hle/service/time/tick_based_steady_clock_core.cpp | ||||
|     hle/service/time/tick_based_steady_clock_core.h | ||||
|     hle/service/time/time.cpp | ||||
|     hle/service/time/time.h | ||||
|     hle/service/time/time_interface.cpp | ||||
|     hle/service/time/time_interface.h | ||||
|     hle/service/time/time_manager.cpp | ||||
|     hle/service/time/time_manager.h | ||||
|     hle/service/time/time_sharedmemory.cpp | ||||
|     hle/service/time/time_sharedmemory.h | ||||
|     hle/service/time/time_zone_content_manager.cpp | ||||
|     hle/service/time/time_zone_content_manager.h | ||||
|     hle/service/time/time_zone_manager.cpp | ||||
|     hle/service/time/time_zone_manager.h | ||||
|     hle/service/time/time_zone_service.cpp | ||||
|     hle/service/time/time_zone_service.h | ||||
|     hle/service/time/time_zone_types.h | ||||
|     hle/service/usb/usb.cpp | ||||
|     hle/service/usb/usb.h | ||||
|     hle/service/vi/display/vi_display.cpp | ||||
| @@ -874,7 +898,7 @@ endif() | ||||
|  | ||||
| create_target_directory_groups(core) | ||||
|  | ||||
| target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb) | ||||
| target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb tz) | ||||
| target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API) | ||||
| if (MINGW) | ||||
|     target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY}) | ||||
|   | ||||
| @@ -40,9 +40,14 @@ | ||||
| #include "core/hle/service/apm/apm_controller.h" | ||||
| #include "core/hle/service/filesystem/filesystem.h" | ||||
| #include "core/hle/service/glue/glue_manager.h" | ||||
| #include "core/hle/service/glue/time/static.h" | ||||
| #include "core/hle/service/psc/time/static.h" | ||||
| #include "core/hle/service/psc/time/steady_clock.h" | ||||
| #include "core/hle/service/psc/time/system_clock.h" | ||||
| #include "core/hle/service/psc/time/time_zone_service.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/set/system_settings_server.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
| #include "core/hle/service/time/time_manager.h" | ||||
| #include "core/internal_network/network.h" | ||||
| #include "core/loader/loader.h" | ||||
| #include "core/memory.h" | ||||
| @@ -130,8 +135,8 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, | ||||
|  | ||||
| struct System::Impl { | ||||
|     explicit Impl(System& system) | ||||
|         : kernel{system}, fs_controller{system}, hid_core{}, room_network{}, cpu_manager{system}, | ||||
|           reporter{system}, applet_manager{system}, profile_manager{}, time_manager{system} {} | ||||
|         : kernel{system}, fs_controller{system}, hid_core{}, room_network{}, | ||||
|           cpu_manager{system}, reporter{system}, applet_manager{system}, profile_manager{} {} | ||||
|  | ||||
|     void Initialize(System& system) { | ||||
|         device_memory = std::make_unique<Core::DeviceMemory>(); | ||||
| @@ -143,8 +148,6 @@ struct System::Impl { | ||||
|         core_timing.SetMulticore(is_multicore); | ||||
|         core_timing.Initialize([&system]() { system.RegisterHostThread(); }); | ||||
|  | ||||
|         RefreshTime(); | ||||
|  | ||||
|         // Create a default fs if one doesn't already exist. | ||||
|         if (virtual_filesystem == nullptr) { | ||||
|             virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); | ||||
| @@ -182,14 +185,57 @@ struct System::Impl { | ||||
|         Initialize(system); | ||||
|     } | ||||
|  | ||||
|     void RefreshTime() { | ||||
|     void RefreshTime(System& system) { | ||||
|         if (!system.IsPoweredOn()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         auto settings_service = | ||||
|             system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", | ||||
|                                                                                     true); | ||||
|         auto static_service_a = | ||||
|             system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:a", true); | ||||
|  | ||||
|         auto static_service_s = | ||||
|             system.ServiceManager().GetService<Service::PSC::Time::StaticService>("time:s", true); | ||||
|  | ||||
|         std::shared_ptr<Service::PSC::Time::SystemClock> user_clock; | ||||
|         static_service_a->GetStandardUserSystemClock(user_clock); | ||||
|  | ||||
|         std::shared_ptr<Service::PSC::Time::SystemClock> local_clock; | ||||
|         static_service_a->GetStandardLocalSystemClock(local_clock); | ||||
|  | ||||
|         std::shared_ptr<Service::PSC::Time::SystemClock> network_clock; | ||||
|         static_service_s->GetStandardNetworkSystemClock(network_clock); | ||||
|  | ||||
|         std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service; | ||||
|         static_service_a->GetTimeZoneService(timezone_service); | ||||
|  | ||||
|         Service::PSC::Time::LocationName name{}; | ||||
|         auto new_name = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue()); | ||||
|         std::memcpy(name.name.data(), new_name.data(), std::min(name.name.size(), new_name.size())); | ||||
|  | ||||
|         timezone_service->SetDeviceLocation(name); | ||||
|  | ||||
|         u64 time_offset = 0; | ||||
|         if (Settings::values.custom_rtc_enabled) { | ||||
|             time_offset = Settings::values.custom_rtc_offset.GetValue(); | ||||
|         } | ||||
|  | ||||
|         const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); | ||||
|         const auto current_time = | ||||
|             std::chrono::duration_cast<std::chrono::seconds>(posix_time).count(); | ||||
|         Settings::values.custom_rtc_differential = | ||||
|             (Settings::values.custom_rtc_enabled ? Settings::values.custom_rtc.GetValue() | ||||
|                                                  : current_time) - | ||||
|             current_time; | ||||
|         const u64 current_time = | ||||
|             +std::chrono::duration_cast<std::chrono::seconds>(posix_time).count(); | ||||
|         const u64 new_time = current_time + time_offset; | ||||
|  | ||||
|         Service::PSC::Time::SystemClockContext context{}; | ||||
|         settings_service->SetUserSystemClockContext(context); | ||||
|         user_clock->SetCurrentTime(new_time); | ||||
|  | ||||
|         local_clock->SetCurrentTime(new_time); | ||||
|  | ||||
|         network_clock->GetSystemClockContext(context); | ||||
|         settings_service->SetNetworkSystemClockContext(context); | ||||
|         network_clock->SetCurrentTime(new_time); | ||||
|     } | ||||
|  | ||||
|     void Run() { | ||||
| @@ -265,9 +311,6 @@ struct System::Impl { | ||||
|         service_manager = std::make_shared<Service::SM::ServiceManager>(kernel); | ||||
|         services = std::make_unique<Service::Services>(service_manager, system); | ||||
|  | ||||
|         // Initialize time manager, which must happen after kernel is created | ||||
|         time_manager.Initialize(); | ||||
|  | ||||
|         is_powered_on = true; | ||||
|         exit_locked = false; | ||||
|         exit_requested = false; | ||||
| @@ -417,7 +460,6 @@ struct System::Impl { | ||||
|         fs_controller.Reset(); | ||||
|         cheat_engine.reset(); | ||||
|         telemetry_session.reset(); | ||||
|         time_manager.Shutdown(); | ||||
|         core_timing.ClearPendingEvents(); | ||||
|         app_loader.reset(); | ||||
|         audio_core.reset(); | ||||
| @@ -533,7 +575,6 @@ struct System::Impl { | ||||
|     /// Service State | ||||
|     Service::Glue::ARPManager arp_manager; | ||||
|     Service::Account::ProfileManager profile_manager; | ||||
|     Service::Time::TimeManager time_manager; | ||||
|  | ||||
|     /// Service manager | ||||
|     std::shared_ptr<Service::SM::ServiceManager> service_manager; | ||||
| @@ -911,14 +952,6 @@ const Service::Account::ProfileManager& System::GetProfileManager() const { | ||||
|     return impl->profile_manager; | ||||
| } | ||||
|  | ||||
| Service::Time::TimeManager& System::GetTimeManager() { | ||||
|     return impl->time_manager; | ||||
| } | ||||
|  | ||||
| const Service::Time::TimeManager& System::GetTimeManager() const { | ||||
|     return impl->time_manager; | ||||
| } | ||||
|  | ||||
| void System::SetExitLocked(bool locked) { | ||||
|     impl->exit_locked = locked; | ||||
| } | ||||
| @@ -1030,13 +1063,9 @@ void System::Exit() { | ||||
| } | ||||
|  | ||||
| void System::ApplySettings() { | ||||
|     impl->RefreshTime(); | ||||
|     impl->RefreshTime(*this); | ||||
|  | ||||
|     if (IsPoweredOn()) { | ||||
|         if (Settings::values.custom_rtc_enabled) { | ||||
|             const s64 posix_time{Settings::values.custom_rtc.GetValue()}; | ||||
|             GetTimeManager().UpdateLocalSystemClockTime(posix_time); | ||||
|         } | ||||
|         Renderer().RefreshBaseSettings(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -73,10 +73,6 @@ namespace SM { | ||||
| class ServiceManager; | ||||
| } // namespace SM | ||||
|  | ||||
| namespace Time { | ||||
| class TimeManager; | ||||
| } // namespace Time | ||||
|  | ||||
| } // namespace Service | ||||
|  | ||||
| namespace Tegra { | ||||
| @@ -381,9 +377,6 @@ public: | ||||
|     [[nodiscard]] Service::Account::ProfileManager& GetProfileManager(); | ||||
|     [[nodiscard]] const Service::Account::ProfileManager& GetProfileManager() const; | ||||
|  | ||||
|     [[nodiscard]] Service::Time::TimeManager& GetTimeManager(); | ||||
|     [[nodiscard]] const Service::Time::TimeManager& GetTimeManager() const; | ||||
|  | ||||
|     [[nodiscard]] Core::Debugger& GetDebugger(); | ||||
|     [[nodiscard]] const Core::Debugger& GetDebugger() const; | ||||
|  | ||||
|   | ||||
| @@ -66,6 +66,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) { | ||||
|     event_fifo_id = 0; | ||||
|     shutting_down = false; | ||||
|     cpu_ticks = 0; | ||||
|     clock->Reset(); | ||||
|     if (is_multicore) { | ||||
|         timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this)); | ||||
|     } | ||||
| @@ -157,7 +158,7 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for (auto h : to_remove) { | ||||
|         for (auto& h : to_remove) { | ||||
|             event_queue.erase(h); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,6 @@ | ||||
| #include "common/swap.h" | ||||
| #include "core/file_sys/system_archive/time_zone_binary.h" | ||||
| #include "core/file_sys/vfs_vector.h" | ||||
| #include "core/hle/service/time/time_zone_types.h" | ||||
|  | ||||
| #include "nx_tzdb.h" | ||||
|  | ||||
|   | ||||
| @@ -10,8 +10,10 @@ | ||||
| #include "core/core.h" | ||||
| #include "core/hle/service/caps/caps_manager.h" | ||||
| #include "core/hle/service/caps/caps_result.h" | ||||
| #include "core/hle/service/time/time_manager.h" | ||||
| #include "core/hle/service/time/time_zone_content_manager.h" | ||||
| #include "core/hle/service/glue/time/static.h" | ||||
| #include "core/hle/service/psc/time/system_clock.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
|  | ||||
| namespace Service::Capture { | ||||
|  | ||||
| @@ -239,10 +241,15 @@ Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, | ||||
|                                     const ApplicationData& app_data, std::span<const u8> image_data, | ||||
|                                     u64 aruid) { | ||||
|     const u64 title_id = system.GetApplicationProcessProgramID(); | ||||
|     const auto& user_clock = system.GetTimeManager().GetStandardUserSystemClockCore(); | ||||
|  | ||||
|     auto static_service = | ||||
|         system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); | ||||
|  | ||||
|     std::shared_ptr<Service::PSC::Time::SystemClock> user_clock{}; | ||||
|     static_service->GetStandardUserSystemClock(user_clock); | ||||
|  | ||||
|     s64 posix_time{}; | ||||
|     Result result = user_clock.GetCurrentTime(system, posix_time); | ||||
|     auto result = user_clock->GetCurrentTime(posix_time); | ||||
|  | ||||
|     if (result.IsError()) { | ||||
|         return result; | ||||
| @@ -257,10 +264,14 @@ Result AlbumManager::SaveEditedScreenShot(ApplicationAlbumEntry& out_entry, | ||||
|                                           const ScreenShotAttribute& attribute, | ||||
|                                           const AlbumFileId& file_id, | ||||
|                                           std::span<const u8> image_data) { | ||||
|     const auto& user_clock = system.GetTimeManager().GetStandardUserSystemClockCore(); | ||||
|     auto static_service = | ||||
|         system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); | ||||
|  | ||||
|     std::shared_ptr<Service::PSC::Time::SystemClock> user_clock{}; | ||||
|     static_service->GetStandardUserSystemClock(user_clock); | ||||
|  | ||||
|     s64 posix_time{}; | ||||
|     Result result = user_clock.GetCurrentTime(system, posix_time); | ||||
|     auto result = user_clock->GetCurrentTime(posix_time); | ||||
|  | ||||
|     if (result.IsError()) { | ||||
|         return result; | ||||
| @@ -455,19 +466,23 @@ Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span<const | ||||
| } | ||||
|  | ||||
| AlbumFileDateTime AlbumManager::ConvertToAlbumDateTime(u64 posix_time) const { | ||||
|     Time::TimeZone::CalendarInfo calendar_date{}; | ||||
|     const auto& time_zone_manager = | ||||
|         system.GetTimeManager().GetTimeZoneContentManager().GetTimeZoneManager(); | ||||
|     auto static_service = | ||||
|         system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); | ||||
|  | ||||
|     time_zone_manager.ToCalendarTimeWithMyRules(posix_time, calendar_date); | ||||
|     std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service{}; | ||||
|     static_service->GetTimeZoneService(timezone_service); | ||||
|  | ||||
|     Service::PSC::Time::CalendarTime calendar_time{}; | ||||
|     Service::PSC::Time::CalendarAdditionalInfo additional_info{}; | ||||
|     timezone_service->ToCalendarTimeWithMyRule(calendar_time, additional_info, posix_time); | ||||
|  | ||||
|     return { | ||||
|         .year = calendar_date.time.year, | ||||
|         .month = calendar_date.time.month, | ||||
|         .day = calendar_date.time.day, | ||||
|         .hour = calendar_date.time.hour, | ||||
|         .minute = calendar_date.time.minute, | ||||
|         .second = calendar_date.time.second, | ||||
|         .year = calendar_time.year, | ||||
|         .month = calendar_time.month, | ||||
|         .day = calendar_time.day, | ||||
|         .hour = calendar_time.hour, | ||||
|         .minute = calendar_time.minute, | ||||
|         .second = calendar_time.second, | ||||
|         .unique_id = 0, | ||||
|     }; | ||||
| } | ||||
|   | ||||
| @@ -8,6 +8,9 @@ | ||||
| #include "core/hle/service/glue/ectx.h" | ||||
| #include "core/hle/service/glue/glue.h" | ||||
| #include "core/hle/service/glue/notif.h" | ||||
| #include "core/hle/service/glue/time/manager.h" | ||||
| #include "core/hle/service/glue/time/static.h" | ||||
| #include "core/hle/service/psc/time/common.h" | ||||
| #include "core/hle/service/server_manager.h" | ||||
|  | ||||
| namespace Service::Glue { | ||||
| @@ -31,6 +34,22 @@ void LoopProcess(Core::System& system) { | ||||
|     // Notification Services for application | ||||
|     server_manager->RegisterNamedService("notif:a", std::make_shared<NOTIF_A>(system)); | ||||
|  | ||||
|     // Time | ||||
|     auto time = std::make_shared<Time::TimeManager>(system); | ||||
|  | ||||
|     server_manager->RegisterNamedService( | ||||
|         "time:u", | ||||
|         std::make_shared<Time::StaticService>( | ||||
|             system, Service::PSC::Time::StaticServiceSetupInfo{0, 0, 0, 0, 0, 0}, time, "time:u")); | ||||
|     server_manager->RegisterNamedService( | ||||
|         "time:a", | ||||
|         std::make_shared<Time::StaticService>( | ||||
|             system, Service::PSC::Time::StaticServiceSetupInfo{1, 1, 0, 1, 0, 0}, time, "time:a")); | ||||
|     server_manager->RegisterNamedService( | ||||
|         "time:r", | ||||
|         std::make_shared<Time::StaticService>( | ||||
|             system, Service::PSC::Time::StaticServiceSetupInfo{0, 0, 0, 0, 1, 0}, time, "time:r")); | ||||
|  | ||||
|     ServerManager::RunServer(std::move(server_manager)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| #include "core/core.h" | ||||
| #include "core/core_timing.h" | ||||
|  | ||||
| #include "common/settings.h" | ||||
| #include "core/file_sys/vfs.h" | ||||
| #include "core/hle/kernel/svc.h" | ||||
| #include "core/hle/service/glue/time/manager.h" | ||||
| @@ -105,10 +106,10 @@ TimeManager::TimeManager(Core::System& system) | ||||
|     res = m_set_sys->GetUserSystemClockContext(user_clock_context); | ||||
|     ASSERT(res == ResultSuccess); | ||||
|  | ||||
|     // TODO this clock should initialise with this epoch time, and be updated somewhere else on | ||||
|     // first boot, but I haven't been able to find that point (likely via ntc's auto correct as it's | ||||
|     // defaulted to be enabled), and to get correct times we need to initialise with the current | ||||
|     // time instead. | ||||
|     // TODO the local clock should initialise with this epoch time, and be updated somewhere else on | ||||
|     // first boot to update it, but I haven't been able to find that point (likely via ntc's auto | ||||
|     // correct as it's defaulted to be enabled). So to get a time that isn't stuck in the past for | ||||
|     // first boot, grab the current real seconds. | ||||
|     auto epoch_time{GetEpochTimeFromInitialYear(m_set_sys)}; | ||||
|     if (user_clock_context == Service::PSC::Time::SystemClockContext{}) { | ||||
|         m_steady_clock_resource.GetRtcTimeInSeconds(epoch_time); | ||||
| @@ -219,6 +220,21 @@ Result TimeManager::SetupTimeZoneServiceCore() { | ||||
|     auto res = m_set_sys->GetDeviceTimeZoneLocationName(name); | ||||
|     ASSERT(res == ResultSuccess); | ||||
|  | ||||
|     auto configured_zone = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue()); | ||||
|     Service::PSC::Time::LocationName new_name{}; | ||||
|     std::memcpy(new_name.name.data(), configured_zone.data(), | ||||
|                 std::min(new_name.name.size(), configured_zone.size())); | ||||
|     if (new_name.name != name.name) { | ||||
|         m_set_sys->SetDeviceTimeZoneLocationName(new_name); | ||||
|         name = new_name; | ||||
|  | ||||
|         std::shared_ptr<Service::PSC::Time::SystemClock> local_clock; | ||||
|         m_time_sm->GetStandardLocalSystemClock(local_clock); | ||||
|         Service::PSC::Time::SystemClockContext context{}; | ||||
|         local_clock->GetSystemClockContext(context); | ||||
|         m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(context.steady_time_point); | ||||
|     } | ||||
|  | ||||
|     Service::PSC::Time::SteadyClockTimePoint time_point{}; | ||||
|     res = m_set_sys->GetDeviceTimeZoneLocationUpdatedTime(time_point); | ||||
|     ASSERT(res == ResultSuccess); | ||||
|   | ||||
| @@ -16,12 +16,12 @@ namespace { | ||||
| [[maybe_unused]] constexpr u32 Max77620RtcSession = 0x3B000001; | ||||
|  | ||||
| Result GetTimeInSeconds(Core::System& system, s64& out_time_s) { | ||||
|     out_time_s = std::chrono::duration_cast<std::chrono::seconds>( | ||||
|                      std::chrono::system_clock::now().time_since_epoch()) | ||||
|                      .count(); | ||||
|  | ||||
|     if (Settings::values.custom_rtc_enabled) { | ||||
|         out_time_s = Settings::values.custom_rtc.GetValue(); | ||||
|     } else { | ||||
|         out_time_s = std::chrono::duration_cast<std::chrono::seconds>( | ||||
|                          std::chrono::system_clock::now().time_since_epoch()) | ||||
|                          .count(); | ||||
|         out_time_s += Settings::values.custom_rtc_offset.GetValue(); | ||||
|     } | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|   | ||||
| @@ -436,7 +436,7 @@ Result StaticService::GetClockSnapshotFromSystemClockContext( | ||||
|  | ||||
| Result StaticService::CalculateStandardUserSystemClockDifferenceByUser( | ||||
|     s64& out_time, Service::PSC::Time::ClockSnapshot& a, Service::PSC::Time::ClockSnapshot& b) { | ||||
|     R_RETURN(m_wrapped_service->CalculateSpanBetween(out_time, a, b)); | ||||
|     R_RETURN(m_wrapped_service->CalculateStandardUserSystemClockDifferenceByUser(out_time, a, b)); | ||||
| } | ||||
|  | ||||
| Result StaticService::CalculateSpanBetween(s64& out_time, Service::PSC::Time::ClockSnapshot& a, | ||||
|   | ||||
| @@ -55,9 +55,9 @@ Result MountTimeZoneBinary(Core::System& system) { | ||||
|  | ||||
|     nca = bis_system->GetEntry(TimeZoneBinaryId, FileSys::ContentRecordType::Data); | ||||
|  | ||||
|     R_UNLESS(nca, ResultUnknown); | ||||
|  | ||||
|     g_time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS()); | ||||
|     if (nca) { | ||||
|         g_time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS()); | ||||
|     } | ||||
|  | ||||
|     if (!g_time_zone_binary_romfs) { | ||||
|         g_time_zone_binary_romfs = FileSys::ExtractRomFS( | ||||
|   | ||||
| @@ -65,6 +65,9 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) { | ||||
| } | ||||
|  | ||||
| void ServiceContext::CloseEvent(Kernel::KEvent* event) { | ||||
|     if (!event) { | ||||
|         return; | ||||
|     } | ||||
|     event->GetReadableEvent().Close(); | ||||
|     event->Close(); | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "core/hle/service/glue/time/static.h" | ||||
| #include "core/hle/service/psc/time/steady_clock.h" | ||||
| #ifdef _MSC_VER | ||||
| #pragma warning(push) | ||||
| #pragma warning(disable : 4701) // Potentially uninitialized local variable 'result' used | ||||
| @@ -29,7 +31,8 @@ | ||||
| #include "core/hle/service/nfc/common/device.h" | ||||
| #include "core/hle/service/nfc/mifare_result.h" | ||||
| #include "core/hle/service/nfc/nfc_result.h" | ||||
| #include "core/hle/service/time/time_manager.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
| #include "hid_core/frontend/emulated_controller.h" | ||||
| #include "hid_core/hid_core.h" | ||||
| #include "hid_core/hid_types.h" | ||||
| @@ -393,8 +396,7 @@ Result NfcDevice::WriteMifare(std::span<const MifareWriteBlockParameter> paramet | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| Result NfcDevice::SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, | ||||
|                                            std::span<const u8> command_data, | ||||
| Result NfcDevice::SendCommandByPassThrough(const s64& timeout, std::span<const u8> command_data, | ||||
|                                            std::span<u8> out_data) { | ||||
|     // Not implemented | ||||
|     return ResultSuccess; | ||||
| @@ -1399,27 +1401,41 @@ void NfcDevice::SetAmiiboName(NFP::AmiiboSettings& settings, | ||||
| } | ||||
|  | ||||
| NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const { | ||||
|     const auto& time_zone_manager = | ||||
|         system.GetTimeManager().GetTimeZoneContentManager().GetTimeZoneManager(); | ||||
|     Time::TimeZone::CalendarInfo calendar_info{}; | ||||
|     auto static_service = | ||||
|         system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); | ||||
|  | ||||
|     std::shared_ptr<Service::Glue::Time::TimeZoneService> timezone_service{}; | ||||
|     static_service->GetTimeZoneService(timezone_service); | ||||
|  | ||||
|     Service::PSC::Time::CalendarTime calendar_time{}; | ||||
|     Service::PSC::Time::CalendarAdditionalInfo additional_info{}; | ||||
|  | ||||
|     NFP::AmiiboDate amiibo_date{}; | ||||
|  | ||||
|     amiibo_date.SetYear(2000); | ||||
|     amiibo_date.SetMonth(1); | ||||
|     amiibo_date.SetDay(1); | ||||
|  | ||||
|     if (time_zone_manager.ToCalendarTime({}, posix_time, calendar_info) == ResultSuccess) { | ||||
|         amiibo_date.SetYear(calendar_info.time.year); | ||||
|         amiibo_date.SetMonth(calendar_info.time.month); | ||||
|         amiibo_date.SetDay(calendar_info.time.day); | ||||
|     if (timezone_service->ToCalendarTimeWithMyRule(calendar_time, additional_info, posix_time) == | ||||
|         ResultSuccess) { | ||||
|         amiibo_date.SetYear(calendar_time.year); | ||||
|         amiibo_date.SetMonth(calendar_time.month); | ||||
|         amiibo_date.SetDay(calendar_time.day); | ||||
|     } | ||||
|  | ||||
|     return amiibo_date; | ||||
| } | ||||
|  | ||||
| u64 NfcDevice::GetCurrentPosixTime() const { | ||||
|     auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; | ||||
|     return standard_steady_clock.GetCurrentTimePoint(system).time_point; | ||||
| s64 NfcDevice::GetCurrentPosixTime() const { | ||||
|     auto static_service = | ||||
|         system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); | ||||
|  | ||||
|     std::shared_ptr<Service::PSC::Time::SteadyClock> steady_clock{}; | ||||
|     static_service->GetStandardSteadyClock(steady_clock); | ||||
|  | ||||
|     Service::PSC::Time::SteadyClockTimePoint time_point{}; | ||||
|     R_ASSERT(steady_clock->GetCurrentTimePoint(time_point)); | ||||
|     return time_point.time_point; | ||||
| } | ||||
|  | ||||
| u64 NfcDevice::RemoveVersionByte(u64 application_id) const { | ||||
|   | ||||
| @@ -11,7 +11,6 @@ | ||||
| #include "core/hle/service/nfc/nfc_types.h" | ||||
| #include "core/hle/service/nfp/nfp_types.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
|  | ||||
| namespace Kernel { | ||||
| class KEvent; | ||||
| @@ -49,8 +48,8 @@ public: | ||||
|  | ||||
|     Result WriteMifare(std::span<const MifareWriteBlockParameter> parameters); | ||||
|  | ||||
|     Result SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, | ||||
|                                     std::span<const u8> command_data, std::span<u8> out_data); | ||||
|     Result SendCommandByPassThrough(const s64& timeout, std::span<const u8> command_data, | ||||
|                                     std::span<u8> out_data); | ||||
|  | ||||
|     Result Mount(NFP::ModelType model_type, NFP::MountTarget mount_target); | ||||
|     Result Unmount(); | ||||
| @@ -108,7 +107,7 @@ private: | ||||
|     NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const; | ||||
|     void SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name) const; | ||||
|     NFP::AmiiboDate GetAmiiboDate(s64 posix_time) const; | ||||
|     u64 GetCurrentPosixTime() const; | ||||
|     s64 GetCurrentPosixTime() const; | ||||
|     u64 RemoveVersionByte(u64 application_id) const; | ||||
|     void UpdateSettingsCrc(); | ||||
|     void UpdateRegisterInfoCrc(); | ||||
|   | ||||
| @@ -6,12 +6,14 @@ | ||||
| #include "common/logging/log.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/glue/time/static.h" | ||||
| #include "core/hle/service/ipc_helpers.h" | ||||
| #include "core/hle/service/nfc/common/device.h" | ||||
| #include "core/hle/service/nfc/common/device_manager.h" | ||||
| #include "core/hle/service/nfc/nfc_result.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
| #include "core/hle/service/time/time_manager.h" | ||||
| #include "core/hle/service/psc/time/steady_clock.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
| #include "hid_core/hid_types.h" | ||||
| #include "hid_core/hid_util.h" | ||||
|  | ||||
| @@ -82,11 +84,19 @@ Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max | ||||
|             continue; | ||||
|         } | ||||
|         if (skip_fatal_errors) { | ||||
|             constexpr u64 MinimumRecoveryTime = 60; | ||||
|             auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; | ||||
|             const u64 elapsed_time = standard_steady_clock.GetCurrentTimePoint(system).time_point - | ||||
|                                      time_since_last_error; | ||||
|             constexpr s64 MinimumRecoveryTime = 60; | ||||
|  | ||||
|             auto static_service = | ||||
|                 system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", | ||||
|                                                                                        true); | ||||
|  | ||||
|             std::shared_ptr<Service::PSC::Time::SteadyClock> steady_clock{}; | ||||
|             static_service->GetStandardSteadyClock(steady_clock); | ||||
|  | ||||
|             Service::PSC::Time::SteadyClockTimePoint time_point{}; | ||||
|             R_ASSERT(steady_clock->GetCurrentTimePoint(time_point)); | ||||
|  | ||||
|             const s64 elapsed_time = time_point.time_point - time_since_last_error; | ||||
|             if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) { | ||||
|                 continue; | ||||
|             } | ||||
| @@ -250,8 +260,7 @@ Result DeviceManager::WriteMifare(u64 device_handle, | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| Result DeviceManager::SendCommandByPassThrough(u64 device_handle, | ||||
|                                                const Time::Clock::TimeSpanType& timeout, | ||||
| Result DeviceManager::SendCommandByPassThrough(u64 device_handle, const s64& timeout, | ||||
|                                                std::span<const u8> command_data, | ||||
|                                                std::span<u8> out_data) { | ||||
|     std::scoped_lock lock{mutex}; | ||||
| @@ -741,8 +750,16 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device, | ||||
|  | ||||
|     if (operation_result == ResultUnknown112 || operation_result == ResultUnknown114 || | ||||
|         operation_result == ResultUnknown115) { | ||||
|         auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; | ||||
|         time_since_last_error = standard_steady_clock.GetCurrentTimePoint(system).time_point; | ||||
|         auto static_service = | ||||
|             system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true); | ||||
|  | ||||
|         std::shared_ptr<Service::PSC::Time::SteadyClock> steady_clock{}; | ||||
|         static_service->GetStandardSteadyClock(steady_clock); | ||||
|  | ||||
|         Service::PSC::Time::SteadyClockTimePoint time_point{}; | ||||
|         R_ASSERT(steady_clock->GetCurrentTimePoint(time_point)); | ||||
|  | ||||
|         time_since_last_error = time_point.time_point; | ||||
|     } | ||||
|  | ||||
|     return operation_result; | ||||
|   | ||||
| @@ -13,7 +13,6 @@ | ||||
| #include "core/hle/service/nfc/nfc_types.h" | ||||
| #include "core/hle/service/nfp/nfp_types.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
| #include "hid_core/hid_types.h" | ||||
|  | ||||
| namespace Service::NFC { | ||||
| @@ -42,7 +41,7 @@ public: | ||||
|                       std::span<MifareReadBlockData> read_data); | ||||
|     Result WriteMifare(u64 device_handle, | ||||
|                        std::span<const MifareWriteBlockParameter> write_parameters); | ||||
|     Result SendCommandByPassThrough(u64 device_handle, const Time::Clock::TimeSpanType& timeout, | ||||
|     Result SendCommandByPassThrough(u64 device_handle, const s64& timeout, | ||||
|                                     std::span<const u8> command_data, std::span<u8> out_data); | ||||
|  | ||||
|     // Nfp device manager | ||||
| @@ -92,7 +91,7 @@ private: | ||||
|     const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const; | ||||
|  | ||||
|     bool is_initialized = false; | ||||
|     u64 time_since_last_error = 0; | ||||
|     s64 time_since_last_error = 0; | ||||
|     mutable std::mutex mutex; | ||||
|     std::array<std::shared_ptr<NfcDevice>, 10> devices{}; | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,6 @@ | ||||
| #include "core/hle/service/nfc/nfc_result.h" | ||||
| #include "core/hle/service/nfc/nfc_types.h" | ||||
| #include "core/hle/service/nfp/nfp_result.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
| #include "hid_core/hid_types.h" | ||||
|  | ||||
| namespace Service::NFC { | ||||
| @@ -261,10 +260,10 @@ void NfcInterface::WriteMifare(HLERequestContext& ctx) { | ||||
| void NfcInterface::SendCommandByPassThrough(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto device_handle{rp.Pop<u64>()}; | ||||
|     const auto timeout{rp.PopRaw<Time::Clock::TimeSpanType>()}; | ||||
|     const auto timeout{rp.PopRaw<s64>()}; | ||||
|     const auto command_data{ctx.ReadBuffer()}; | ||||
|     LOG_INFO(Service_NFC, "(STUBBED) called, device_handle={}, timeout={}, data_size={}", | ||||
|              device_handle, timeout.ToSeconds(), command_data.size()); | ||||
|              device_handle, timeout, command_data.size()); | ||||
|  | ||||
|     std::vector<u8> out_data(1); | ||||
|     auto result = | ||||
|   | ||||
| @@ -415,4 +415,4 @@ std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage | ||||
|         return std::nullopt; | ||||
|     } | ||||
| } | ||||
| } // namespace Service::NS | ||||
| } // namespace Service::NS | ||||
|   | ||||
| @@ -5,10 +5,7 @@ | ||||
|  | ||||
| #include <optional> | ||||
| #include "common/common_types.h" | ||||
|  | ||||
| namespace Service::Set { | ||||
| enum class LanguageCode : u64; | ||||
| } | ||||
| #include "core/hle/service/set/system_settings_server.h" | ||||
|  | ||||
| namespace Service::NS { | ||||
| /// This is nn::ns::detail::ApplicationLanguage | ||||
|   | ||||
| @@ -4,9 +4,13 @@ | ||||
| #include <memory> | ||||
|  | ||||
| #include "common/logging/log.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/service/ipc_helpers.h" | ||||
| #include "core/hle/service/psc/psc.h" | ||||
| #include "core/hle/service/server_manager.h" | ||||
| #include "core/hle/service/psc/time/manager.h" | ||||
| #include "core/hle/service/psc/time/power_state_service.h" | ||||
| #include "core/hle/service/psc/time/service_manager.h" | ||||
| #include "core/hle/service/psc/time/static.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Service::PSC { | ||||
| @@ -76,6 +80,17 @@ void LoopProcess(Core::System& system) { | ||||
|  | ||||
|     server_manager->RegisterNamedService("psc:c", std::make_shared<IPmControl>(system)); | ||||
|     server_manager->RegisterNamedService("psc:m", std::make_shared<IPmService>(system)); | ||||
|  | ||||
|     auto time = std::make_shared<Time::TimeManager>(system); | ||||
|  | ||||
|     server_manager->RegisterNamedService( | ||||
|         "time:m", std::make_shared<Time::ServiceManager>(system, time, server_manager.get())); | ||||
|     server_manager->RegisterNamedService( | ||||
|         "time:su", std::make_shared<Time::StaticService>( | ||||
|                        system, Time::StaticServiceSetupInfo{0, 0, 0, 0, 0, 1}, time, "time:su")); | ||||
|     server_manager->RegisterNamedService("time:al", | ||||
|                                          std::make_shared<Time::IAlarmService>(system, time)); | ||||
|  | ||||
|     ServerManager::RunServer(std::move(server_manager)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -44,10 +44,11 @@ void StandardSteadyClockCore::GetContinuousAdjustment( | ||||
|  | ||||
| void StandardSteadyClockCore::UpdateContinuousAdjustmentTime(s64 in_time) { | ||||
|     auto ticks{m_system.CoreTiming().GetClockTicks()}; | ||||
|     auto global_time_ns{ConvertToTimeSpan(ticks).count()}; | ||||
|     auto expected_time{((global_time_ns - m_continuous_adjustment_time_point.rtc_offset) * | ||||
|     auto uptime_ns{ConvertToTimeSpan(ticks).count()}; | ||||
|     auto adjusted_time{((uptime_ns - m_continuous_adjustment_time_point.rtc_offset) * | ||||
|                         m_continuous_adjustment_time_point.diff_scale) >> | ||||
|                        m_continuous_adjustment_time_point.shift_amount}; | ||||
|     auto expected_time{adjusted_time + m_continuous_adjustment_time_point.lower}; | ||||
|  | ||||
|     auto last_time_point{m_continuous_adjustment_time_point.upper}; | ||||
|     m_continuous_adjustment_time_point.upper = in_time; | ||||
| @@ -57,7 +58,7 @@ void StandardSteadyClockCore::UpdateContinuousAdjustmentTime(s64 in_time) { | ||||
|  | ||||
|     auto new_diff{in_time < expected_time ? -55 : 55}; | ||||
|  | ||||
|     m_continuous_adjustment_time_point.rtc_offset = global_time_ns; | ||||
|     m_continuous_adjustment_time_point.rtc_offset = uptime_ns; | ||||
|     m_continuous_adjustment_time_point.shift_amount = expected_time == in_time ? 0 : 14; | ||||
|     m_continuous_adjustment_time_point.diff_scale = expected_time == in_time ? 0 : new_diff; | ||||
|     m_continuous_adjustment_time_point.lower = expected_time; | ||||
|   | ||||
| @@ -19,11 +19,8 @@ StandardUserSystemClockCore::~StandardUserSystemClockCore() { | ||||
| } | ||||
|  | ||||
| Result StandardUserSystemClockCore::SetAutomaticCorrection(bool automatic_correction) { | ||||
|     if (m_automatic_correction == automatic_correction || | ||||
|         !m_network_system_clock.CheckClockSourceMatches()) { | ||||
|         m_automatic_correction = automatic_correction; | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
|     R_SUCCEED_IF(m_automatic_correction == automatic_correction); | ||||
|     R_SUCCEED_IF(!m_network_system_clock.CheckClockSourceMatches()); | ||||
|  | ||||
|     SystemClockContext context{}; | ||||
|     R_TRY(m_network_system_clock.GetContext(context)); | ||||
|   | ||||
| @@ -348,9 +348,11 @@ Result ServiceManager::SetupStandardLocalSystemClockCore(SystemClockContext& con | ||||
| Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& context, | ||||
|                                                            s64 accuracy) { | ||||
|     // TODO this is a hack! The network clock should be updated independently, from the ntc service | ||||
|     // and maybe elsewhere. We do not do that, so fix the network clock to the local clock on boot | ||||
|     // and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot | ||||
|     // to avoid it being stuck at 0. | ||||
|     m_local_system_clock.GetContext(context); | ||||
|     if (context == Service::PSC::Time::SystemClockContext{}) { | ||||
|         m_local_system_clock.GetContext(context); | ||||
|     } | ||||
|  | ||||
|     m_network_system_clock.SetContextWriter(m_network_system_context_writer); | ||||
|     m_network_system_clock.Initialize(context, accuracy); | ||||
| @@ -361,9 +363,12 @@ Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& c | ||||
|  | ||||
| Result ServiceManager::SetupStandardUserSystemClockCore(SteadyClockTimePoint& time_point, | ||||
|                                                         bool automatic_correction) { | ||||
|     // TODO this is a hack! I'm not sure where this clock's time point is initialised, but we don't | ||||
|     // want it at 0. | ||||
|     // m_local_system_clock.GetCurrentTimePoint(time_point); | ||||
|     // TODO this is a hack! The user clock should be updated independently, from the ntc service | ||||
|     // and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot | ||||
|     // to avoid it being stuck at 0. | ||||
|     if (time_point == Service::PSC::Time::SteadyClockTimePoint{}) { | ||||
|         m_local_system_clock.GetCurrentTimePoint(time_point); | ||||
|     } | ||||
|  | ||||
|     m_user_system_clock.SetAutomaticCorrection(automatic_correction); | ||||
|     m_user_system_clock.SetTimePointAndSignal(time_point); | ||||
|   | ||||
| @@ -459,14 +459,25 @@ Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(s64& out_ | ||||
|                                                                        ClockSnapshot& b) { | ||||
|     auto diff_s = | ||||
|         std::chrono::seconds(b.user_context.offset) - std::chrono::seconds(a.user_context.offset); | ||||
|     out_time = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count(); | ||||
|  | ||||
|     if (a.user_context != b.user_context || | ||||
|         (a.is_automatic_correction_enabled && b.is_automatic_correction_enabled) || | ||||
|         !a.network_context.steady_time_point.IdMatches(b.network_context.steady_time_point)) { | ||||
|     if (a.user_context == b.user_context || | ||||
|         !a.user_context.steady_time_point.IdMatches(b.user_context.steady_time_point)) { | ||||
|         out_time = 0; | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
|  | ||||
|     if (!a.is_automatic_correction_enabled || !b.is_automatic_correction_enabled) { | ||||
|         out_time = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count(); | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
|  | ||||
|     if (a.network_context.steady_time_point.IdMatches(a.steady_clock_time_point) || | ||||
|         b.network_context.steady_time_point.IdMatches(b.steady_clock_time_point)) { | ||||
|         out_time = 0; | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
|  | ||||
|     out_time = std::chrono::duration_cast<std::chrono::nanoseconds>(diff_s).count(); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -228,8 +228,8 @@ void TimeZoneService::Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx) { | ||||
|  | ||||
| // =============================== Implementations =========================== | ||||
|  | ||||
| Result TimeZoneService::GetDeviceLocationName(LocationName& out_lcoation_name) { | ||||
|     R_RETURN(m_time_zone.GetLocationName(out_lcoation_name)); | ||||
| Result TimeZoneService::GetDeviceLocationName(LocationName& out_location_name) { | ||||
|     R_RETURN(m_time_zone.GetLocationName(out_location_name)); | ||||
| } | ||||
|  | ||||
| Result TimeZoneService::GetTotalLocationNameCount(u32& out_count) { | ||||
|   | ||||
| @@ -26,7 +26,7 @@ public: | ||||
|  | ||||
|     ~TimeZoneService() override = default; | ||||
|  | ||||
|     Result GetDeviceLocationName(LocationName& out_lcoation_name); | ||||
|     Result GetDeviceLocationName(LocationName& out_location_name); | ||||
|     Result GetTotalLocationNameCount(u32& out_count); | ||||
|     Result GetTimeZoneRuleVersion(RuleVersion& out_rule_version); | ||||
|     Result GetDeviceLocationNameAndUpdatedTime(SteadyClockTimePoint& out_time_point, | ||||
|   | ||||
| @@ -66,7 +66,6 @@ | ||||
| #include "core/hle/service/sockets/sockets.h" | ||||
| #include "core/hle/service/spl/spl_module.h" | ||||
| #include "core/hle/service/ssl/ssl.h" | ||||
| #include "core/hle/service/time/time.h" | ||||
| #include "core/hle/service/usb/usb.h" | ||||
| #include "core/hle/service/vi/vi.h" | ||||
| #include "core/reporter.h" | ||||
| @@ -246,6 +245,9 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system | ||||
|     kernel.RunOnGuestCoreProcess("fatal",      [&] { Fatal::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("fgm",        [&] { FGM::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("friends",    [&] { Friend::LoopProcess(system); }); | ||||
|     // glue depends on settings and psc, so they must come first | ||||
|     kernel.RunOnGuestCoreProcess("settings",   [&] { Set::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("psc",        [&] { PSC::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("glue",       [&] { Glue::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("grc",        [&] { GRC::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("hid",        [&] { HID::LoopProcess(system); }); | ||||
| @@ -269,13 +271,10 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system | ||||
|     kernel.RunOnGuestCoreProcess("pcv",        [&] { PCV::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("prepo",      [&] { PlayReport::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("ProcessManager", [&] { PM::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("psc",        [&] { PSC::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("ptm",        [&] { PTM::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("ro",         [&] { RO::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("settings",   [&] { Set::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("spl",        [&] { SPL::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("ssl",        [&] { SSL::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("time",       [&] { Time::LoopProcess(system); }); | ||||
|     kernel.RunOnGuestCoreProcess("usb",        [&] { USB::LoopProcess(system); }); | ||||
|     // clang-format on | ||||
| } | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/uuid.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
| #include "core/hle/service/psc/time/common.h" | ||||
|  | ||||
| namespace Service::Set { | ||||
|  | ||||
| @@ -29,14 +29,14 @@ static_assert(sizeof(InitialLaunchFlag) == 4, "InitialLaunchFlag is an invalid s | ||||
| struct InitialLaunchSettings { | ||||
|     InitialLaunchFlag flags; | ||||
|     INSERT_PADDING_BYTES(0x4); | ||||
|     Service::Time::Clock::SteadyClockTimePoint timestamp; | ||||
|     Service::PSC::Time::SteadyClockTimePoint timestamp; | ||||
| }; | ||||
| static_assert(sizeof(InitialLaunchSettings) == 0x20, "InitialLaunchSettings is incorrect size"); | ||||
|  | ||||
| #pragma pack(push, 4) | ||||
| struct InitialLaunchSettingsPacked { | ||||
|     InitialLaunchFlag flags; | ||||
|     Service::Time::Clock::SteadyClockTimePoint timestamp; | ||||
|     Service::PSC::Time::SteadyClockTimePoint timestamp; | ||||
| }; | ||||
| #pragma pack(pop) | ||||
| static_assert(sizeof(InitialLaunchSettingsPacked) == 0x1C, | ||||
|   | ||||
| @@ -8,7 +8,6 @@ | ||||
| #include "common/common_types.h" | ||||
| #include "common/uuid.h" | ||||
| #include "core/hle/service/set/settings_types.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
|  | ||||
| namespace Service::Set { | ||||
|  | ||||
|   | ||||
| @@ -45,7 +45,7 @@ SystemSettings DefaultSystemSettings() { | ||||
|     }; | ||||
|  | ||||
|     settings.device_time_zone_location_name = {"UTC"}; | ||||
|     settings.user_system_clock_automatic_correction_enabled = false; | ||||
|     settings.user_system_clock_automatic_correction_enabled = true; | ||||
|  | ||||
|     settings.primary_album_storage = PrimaryAlbumStorage::SdCard; | ||||
|     settings.battery_percentage_flag = true; | ||||
|   | ||||
| @@ -12,7 +12,6 @@ | ||||
| #include "common/vector_math.h" | ||||
| #include "core/hle/service/set/setting_formats/private_settings.h" | ||||
| #include "core/hle/service/set/settings_types.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
|  | ||||
| namespace Service::Set { | ||||
|  | ||||
| @@ -197,12 +196,14 @@ struct SystemSettings { | ||||
|     std::array<u8, 0x2C> backlight_settings_mixed_up; | ||||
|     INSERT_PADDING_BYTES(0x64); // Reserved | ||||
|  | ||||
|     Service::Time::Clock::SystemClockContext user_system_clock_context; | ||||
|     Service::Time::Clock::SystemClockContext network_system_clock_context; | ||||
|     // nn::time::SystemClockContext | ||||
|     Service::PSC::Time::SystemClockContext user_system_clock_context; | ||||
|     Service::PSC::Time::SystemClockContext network_system_clock_context; | ||||
|     bool user_system_clock_automatic_correction_enabled; | ||||
|     INSERT_PADDING_BYTES(0x3); | ||||
|     INSERT_PADDING_BYTES(0x4); // Reserved | ||||
|     Service::Time::Clock::SteadyClockTimePoint | ||||
|     // nn::time::SteadyClockTimePoint | ||||
|     Service::PSC::Time::SteadyClockTimePoint | ||||
|         user_system_clock_automatic_correction_updated_time_point; | ||||
|     INSERT_PADDING_BYTES(0x10); // Reserved | ||||
|  | ||||
| @@ -280,9 +281,12 @@ struct SystemSettings { | ||||
|     bool requires_run_repair_time_reviser; | ||||
|     INSERT_PADDING_BYTES(0x6B); // Reserved | ||||
|  | ||||
|     Service::Time::TimeZone::LocationName device_time_zone_location_name; | ||||
|     // nn::time::LocationName | ||||
|     Service::PSC::Time::LocationName device_time_zone_location_name; | ||||
|     INSERT_PADDING_BYTES(0x4); // Reserved | ||||
|     Service::Time::Clock::SteadyClockTimePoint device_time_zone_location_updated_time; | ||||
|     // nn::time::SteadyClockTimePoint | ||||
|     Service::PSC::Time::SteadyClockTimePoint device_time_zone_location_updated_time; | ||||
|  | ||||
|     INSERT_PADDING_BYTES(0xC0); // Reserved | ||||
|  | ||||
|     // nn::settings::system::PrimaryAlbumStorage | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/uuid.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
| #include "core/hle/service/psc/time/common.h" | ||||
|  | ||||
| namespace Service::Set { | ||||
|  | ||||
| @@ -365,7 +365,7 @@ struct EulaVersion { | ||||
|     EulaVersionClockType clock_type; | ||||
|     INSERT_PADDING_BYTES(0x4); | ||||
|     s64 posix_time; | ||||
|     Time::Clock::SteadyClockTimePoint timestamp; | ||||
|     Service::PSC::Time::SteadyClockTimePoint timestamp; | ||||
| }; | ||||
| static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size"); | ||||
|  | ||||
| @@ -398,14 +398,14 @@ static_assert(sizeof(HomeMenuScheme) == 0x14, "HomeMenuScheme is incorrect size" | ||||
| struct InitialLaunchSettings { | ||||
|     InitialLaunchFlag flags; | ||||
|     INSERT_PADDING_BYTES(0x4); | ||||
|     Service::Time::Clock::SteadyClockTimePoint timestamp; | ||||
|     Service::PSC::Time::SteadyClockTimePoint timestamp; | ||||
| }; | ||||
| static_assert(sizeof(InitialLaunchSettings) == 0x20, "InitialLaunchSettings is incorrect size"); | ||||
|  | ||||
| #pragma pack(push, 4) | ||||
| struct InitialLaunchSettingsPacked { | ||||
|     InitialLaunchFlag flags; | ||||
|     Service::Time::Clock::SteadyClockTimePoint timestamp; | ||||
|     Service::PSC::Time::SteadyClockTimePoint timestamp; | ||||
| }; | ||||
| #pragma pack(pop) | ||||
| static_assert(sizeof(InitialLaunchSettingsPacked) == 0x1C, | ||||
|   | ||||
| @@ -489,11 +489,10 @@ void ISystemSettingsServer::SetExternalSteadyClockSourceId(HLERequestContext& ct | ||||
| void ISystemSettingsServer::GetUserSystemClockContext(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     Service::Time::Clock::SystemClockContext context{}; | ||||
|     Service::PSC::Time::SystemClockContext context{}; | ||||
|     auto res = GetUserSystemClockContext(context); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, | ||||
|                             2 + sizeof(Service::Time::Clock::SystemClockContext) / sizeof(u32)}; | ||||
|     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::SystemClockContext) / sizeof(u32)}; | ||||
|     rb.Push(res); | ||||
|     rb.PushRaw(context); | ||||
| } | ||||
| @@ -502,7 +501,7 @@ void ISystemSettingsServer::SetUserSystemClockContext(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     auto context{rp.PopRaw<Service::Time::Clock::SystemClockContext>()}; | ||||
|     auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()}; | ||||
|  | ||||
|     auto res = SetUserSystemClockContext(context); | ||||
|  | ||||
| @@ -809,19 +808,19 @@ void ISystemSettingsServer::GetQuestFlag(HLERequestContext& ctx) { | ||||
| void ISystemSettingsServer::GetDeviceTimeZoneLocationName(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     Service::Time::TimeZone::LocationName name{}; | ||||
|     Service::PSC::Time::LocationName name{}; | ||||
|     auto res = GetDeviceTimeZoneLocationName(name); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::Time::TimeZone::LocationName) / sizeof(u32)}; | ||||
|     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::LocationName) / sizeof(u32)}; | ||||
|     rb.Push(res); | ||||
|     rb.PushRaw<Service::Time::TimeZone::LocationName>(name); | ||||
|     rb.PushRaw<Service::PSC::Time::LocationName>(name); | ||||
| } | ||||
|  | ||||
| void ISystemSettingsServer::SetDeviceTimeZoneLocationName(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     auto name{rp.PopRaw<Service::Time::TimeZone::LocationName>()}; | ||||
|     auto name{rp.PopRaw<Service::PSC::Time::LocationName>()}; | ||||
|  | ||||
|     auto res = SetDeviceTimeZoneLocationName(name); | ||||
|  | ||||
| @@ -843,11 +842,10 @@ void ISystemSettingsServer::SetRegionCode(HLERequestContext& ctx) { | ||||
| void ISystemSettingsServer::GetNetworkSystemClockContext(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     Service::Time::Clock::SystemClockContext context{}; | ||||
|     Service::PSC::Time::SystemClockContext context{}; | ||||
|     auto res = GetNetworkSystemClockContext(context); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, | ||||
|                             2 + sizeof(Service::Time::Clock::SystemClockContext) / sizeof(u32)}; | ||||
|     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::SystemClockContext) / sizeof(u32)}; | ||||
|     rb.Push(res); | ||||
|     rb.PushRaw(context); | ||||
| } | ||||
| @@ -856,7 +854,7 @@ void ISystemSettingsServer::SetNetworkSystemClockContext(HLERequestContext& ctx) | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     auto context{rp.PopRaw<Service::Time::Clock::SystemClockContext>()}; | ||||
|     auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()}; | ||||
|  | ||||
|     auto res = SetNetworkSystemClockContext(context); | ||||
|  | ||||
| @@ -1136,19 +1134,19 @@ void ISystemSettingsServer::GetKeyboardLayout(HLERequestContext& ctx) { | ||||
| void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     Service::Time::Clock::SteadyClockTimePoint time_point{}; | ||||
|     Service::PSC::Time::SteadyClockTimePoint time_point{}; | ||||
|     auto res = GetDeviceTimeZoneLocationUpdatedTime(time_point); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(res); | ||||
|     rb.PushRaw<Service::Time::Clock::SteadyClockTimePoint>(time_point); | ||||
|     rb.PushRaw<Service::PSC::Time::SteadyClockTimePoint>(time_point); | ||||
| } | ||||
|  | ||||
| void ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     auto time_point{rp.PopRaw<Service::Time::Clock::SteadyClockTimePoint>()}; | ||||
|     auto time_point{rp.PopRaw<Service::PSC::Time::SteadyClockTimePoint>()}; | ||||
|  | ||||
|     auto res = SetDeviceTimeZoneLocationUpdatedTime(time_point); | ||||
|  | ||||
| @@ -1160,12 +1158,12 @@ void ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime( | ||||
|     HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     Service::Time::Clock::SteadyClockTimePoint time_point{}; | ||||
|     Service::PSC::Time::SteadyClockTimePoint time_point{}; | ||||
|     auto res = GetUserSystemClockAutomaticCorrectionUpdatedTime(time_point); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(res); | ||||
|     rb.PushRaw<Service::Time::Clock::SteadyClockTimePoint>(time_point); | ||||
|     rb.PushRaw<Service::PSC::Time::SteadyClockTimePoint>(time_point); | ||||
| } | ||||
|  | ||||
| void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime( | ||||
| @@ -1173,7 +1171,7 @@ void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime( | ||||
|     LOG_INFO(Service_SET, "called"); | ||||
|  | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     auto time_point{rp.PopRaw<Service::Time::Clock::SteadyClockTimePoint>()}; | ||||
|     auto time_point{rp.PopRaw<Service::PSC::Time::SteadyClockTimePoint>()}; | ||||
|  | ||||
|     auto res = SetUserSystemClockAutomaticCorrectionUpdatedTime(time_point); | ||||
|  | ||||
| @@ -1252,25 +1250,25 @@ void ISystemSettingsServer::StoreSettings() { | ||||
|     auto system_dir = | ||||
|         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050"; | ||||
|     if (!StoreSettingsFile(system_dir, m_system_settings)) { | ||||
|         LOG_ERROR(HW_GPU, "Failed to store System settings"); | ||||
|         LOG_ERROR(Service_SET, "Failed to store System settings"); | ||||
|     } | ||||
|  | ||||
|     auto private_dir = | ||||
|         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000052"; | ||||
|     if (!StoreSettingsFile(private_dir, m_private_settings)) { | ||||
|         LOG_ERROR(HW_GPU, "Failed to store Private settings"); | ||||
|         LOG_ERROR(Service_SET, "Failed to store Private settings"); | ||||
|     } | ||||
|  | ||||
|     auto device_dir = | ||||
|         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000053"; | ||||
|     if (!StoreSettingsFile(device_dir, m_device_settings)) { | ||||
|         LOG_ERROR(HW_GPU, "Failed to store Device settings"); | ||||
|         LOG_ERROR(Service_SET, "Failed to store Device settings"); | ||||
|     } | ||||
|  | ||||
|     auto appln_dir = | ||||
|         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000054"; | ||||
|     if (!StoreSettingsFile(appln_dir, m_appln_settings)) { | ||||
|         LOG_ERROR(HW_GPU, "Failed to store ApplLn settings"); | ||||
|         LOG_ERROR(Service_SET, "Failed to store ApplLn settings"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -1313,39 +1311,39 @@ Result ISystemSettingsServer::SetExternalSteadyClockSourceId(Common::UUID id) { | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::GetUserSystemClockContext( | ||||
|     Service::Time::Clock::SystemClockContext& out_context) { | ||||
|     Service::PSC::Time::SystemClockContext& out_context) { | ||||
|     out_context = m_system_settings.user_system_clock_context; | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::SetUserSystemClockContext( | ||||
|     Service::Time::Clock::SystemClockContext& context) { | ||||
|     Service::PSC::Time::SystemClockContext& context) { | ||||
|     m_system_settings.user_system_clock_context = context; | ||||
|     SetSaveNeeded(); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::GetDeviceTimeZoneLocationName( | ||||
|     Service::Time::TimeZone::LocationName& out_name) { | ||||
|     Service::PSC::Time::LocationName& out_name) { | ||||
|     out_name = m_system_settings.device_time_zone_location_name; | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::SetDeviceTimeZoneLocationName( | ||||
|     Service::Time::TimeZone::LocationName& name) { | ||||
|     Service::PSC::Time::LocationName& name) { | ||||
|     m_system_settings.device_time_zone_location_name = name; | ||||
|     SetSaveNeeded(); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::GetNetworkSystemClockContext( | ||||
|     Service::Time::Clock::SystemClockContext& out_context) { | ||||
|     Service::PSC::Time::SystemClockContext& out_context) { | ||||
|     out_context = m_system_settings.network_system_clock_context; | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::SetNetworkSystemClockContext( | ||||
|     Service::Time::Clock::SystemClockContext& context) { | ||||
|     Service::PSC::Time::SystemClockContext& context) { | ||||
|     m_system_settings.network_system_clock_context = context; | ||||
|     SetSaveNeeded(); | ||||
|     R_SUCCEED(); | ||||
| @@ -1374,26 +1372,26 @@ Result ISystemSettingsServer::GetExternalSteadyClockInternalOffset(s64& out_offs | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime( | ||||
|     Service::Time::Clock::SteadyClockTimePoint& out_time_point) { | ||||
|     Service::PSC::Time::SteadyClockTimePoint& out_time_point) { | ||||
|     out_time_point = m_system_settings.device_time_zone_location_updated_time; | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime( | ||||
|     Service::Time::Clock::SteadyClockTimePoint& time_point) { | ||||
|     Service::PSC::Time::SteadyClockTimePoint& time_point) { | ||||
|     m_system_settings.device_time_zone_location_updated_time = time_point; | ||||
|     SetSaveNeeded(); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime( | ||||
|     Service::Time::Clock::SteadyClockTimePoint& out_time_point) { | ||||
|     Service::PSC::Time::SteadyClockTimePoint& out_time_point) { | ||||
|     out_time_point = m_system_settings.user_system_clock_automatic_correction_updated_time_point; | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
| Result ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime( | ||||
|     Service::Time::Clock::SteadyClockTimePoint out_time_point) { | ||||
|     Service::PSC::Time::SteadyClockTimePoint out_time_point) { | ||||
|     m_system_settings.user_system_clock_automatic_correction_updated_time_point = out_time_point; | ||||
|     SetSaveNeeded(); | ||||
|     R_SUCCEED(); | ||||
|   | ||||
| @@ -11,14 +11,13 @@ | ||||
| #include "common/polyfill_thread.h" | ||||
| #include "common/uuid.h" | ||||
| #include "core/hle/result.h" | ||||
| #include "core/hle/service/psc/time/common.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/set/setting_formats/appln_settings.h" | ||||
| #include "core/hle/service/set/setting_formats/device_settings.h" | ||||
| #include "core/hle/service/set/setting_formats/private_settings.h" | ||||
| #include "core/hle/service/set/setting_formats/system_settings.h" | ||||
| #include "core/hle/service/set/settings_types.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
| #include "core/hle/service/time/time_zone_types.h" | ||||
|  | ||||
| namespace Core { | ||||
| class System; | ||||
| @@ -51,24 +50,24 @@ public: | ||||
|  | ||||
|     Result GetExternalSteadyClockSourceId(Common::UUID& out_id); | ||||
|     Result SetExternalSteadyClockSourceId(Common::UUID id); | ||||
|     Result GetUserSystemClockContext(Service::Time::Clock::SystemClockContext& out_context); | ||||
|     Result SetUserSystemClockContext(Service::Time::Clock::SystemClockContext& context); | ||||
|     Result GetDeviceTimeZoneLocationName(Service::Time::TimeZone::LocationName& out_name); | ||||
|     Result SetDeviceTimeZoneLocationName(Service::Time::TimeZone::LocationName& name); | ||||
|     Result GetNetworkSystemClockContext(Service::Time::Clock::SystemClockContext& out_context); | ||||
|     Result SetNetworkSystemClockContext(Service::Time::Clock::SystemClockContext& context); | ||||
|     Result GetUserSystemClockContext(Service::PSC::Time::SystemClockContext& out_context); | ||||
|     Result SetUserSystemClockContext(Service::PSC::Time::SystemClockContext& context); | ||||
|     Result GetDeviceTimeZoneLocationName(Service::PSC::Time::LocationName& out_name); | ||||
|     Result SetDeviceTimeZoneLocationName(Service::PSC::Time::LocationName& name); | ||||
|     Result GetNetworkSystemClockContext(Service::PSC::Time::SystemClockContext& out_context); | ||||
|     Result SetNetworkSystemClockContext(Service::PSC::Time::SystemClockContext& context); | ||||
|     Result IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled); | ||||
|     Result SetUserSystemClockAutomaticCorrectionEnabled(bool enabled); | ||||
|     Result SetExternalSteadyClockInternalOffset(s64 offset); | ||||
|     Result GetExternalSteadyClockInternalOffset(s64& out_offset); | ||||
|     Result GetDeviceTimeZoneLocationUpdatedTime( | ||||
|         Service::Time::Clock::SteadyClockTimePoint& out_time_point); | ||||
|         Service::PSC::Time::SteadyClockTimePoint& out_time_point); | ||||
|     Result SetDeviceTimeZoneLocationUpdatedTime( | ||||
|         Service::Time::Clock::SteadyClockTimePoint& time_point); | ||||
|         Service::PSC::Time::SteadyClockTimePoint& time_point); | ||||
|     Result GetUserSystemClockAutomaticCorrectionUpdatedTime( | ||||
|         Service::Time::Clock::SteadyClockTimePoint& out_time_point); | ||||
|         Service::PSC::Time::SteadyClockTimePoint& out_time_point); | ||||
|     Result SetUserSystemClockAutomaticCorrectionUpdatedTime( | ||||
|         Service::Time::Clock::SteadyClockTimePoint time_point); | ||||
|         Service::PSC::Time::SteadyClockTimePoint time_point); | ||||
|  | ||||
| private: | ||||
|     void SetLanguageCode(HLERequestContext& ctx); | ||||
| @@ -147,8 +146,8 @@ private: | ||||
|     PrivateSettings m_private_settings{}; | ||||
|     DeviceSettings m_device_settings{}; | ||||
|     ApplnSettings m_appln_settings{}; | ||||
|     std::jthread m_save_thread; | ||||
|     std::mutex m_save_needed_mutex; | ||||
|     std::jthread m_save_thread; | ||||
|     bool m_save_needed{false}; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <chrono> | ||||
| #include <memory> | ||||
| #include <mutex> | ||||
| #include <string> | ||||
| @@ -10,6 +11,7 @@ | ||||
|  | ||||
| #include "common/concepts.h" | ||||
| #include "core/hle/kernel/k_port.h" | ||||
| #include "core/hle/kernel/svc.h" | ||||
| #include "core/hle/result.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| @@ -62,12 +64,21 @@ public: | ||||
|     Result GetServicePort(Kernel::KClientPort** out_client_port, const std::string& name); | ||||
|  | ||||
|     template <Common::DerivedFrom<SessionRequestHandler> T> | ||||
|     std::shared_ptr<T> GetService(const std::string& service_name) const { | ||||
|     std::shared_ptr<T> GetService(const std::string& service_name, bool block = false) const { | ||||
|         auto service = registered_services.find(service_name); | ||||
|         if (service == registered_services.end()) { | ||||
|         if (service == registered_services.end() && !block) { | ||||
|             LOG_DEBUG(Service, "Can't find service: {}", service_name); | ||||
|             return nullptr; | ||||
|         } else if (block) { | ||||
|             using namespace std::literals::chrono_literals; | ||||
|             while (service == registered_services.end()) { | ||||
|                 Kernel::Svc::SleepThread( | ||||
|                     kernel.System(), | ||||
|                     std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count()); | ||||
|                 service = registered_services.find(service_name); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return std::static_pointer_cast<T>(service->second()); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -545,4 +545,4 @@ TEST_CASE("MemoryTracker: Cached write downloads") { | ||||
|     REQUIRE(!memory_track->IsRegionGpuModified(c + PAGE, PAGE)); | ||||
|     memory_track->MarkRegionAsCpuModified(c, WORD); | ||||
|     REQUIRE(rasterizer.Count() == 0); | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -67,4 +67,4 @@ public: | ||||
|     size_t size_slots{}; | ||||
| }; | ||||
|  | ||||
| } // namespace VideoCommon | ||||
| } // namespace VideoCommon | ||||
|   | ||||
| @@ -175,4 +175,4 @@ protected: | ||||
|     std::unique_ptr<QueryCacheBaseImpl> impl; | ||||
| }; | ||||
|  | ||||
| } // namespace VideoCommon | ||||
| } // namespace VideoCommon | ||||
|   | ||||
| @@ -146,4 +146,4 @@ protected: | ||||
|     std::deque<size_t> old_queries; | ||||
| }; | ||||
|  | ||||
| } // namespace VideoCommon | ||||
| } // namespace VideoCommon | ||||
|   | ||||
| @@ -71,4 +71,4 @@ enum class ReductionOp : u32 { | ||||
|     MaxReductionOp, | ||||
| }; | ||||
|  | ||||
| } // namespace VideoCommon | ||||
| } // namespace VideoCommon | ||||
|   | ||||
| @@ -13,4 +13,4 @@ struct RasterizerDownloadArea { | ||||
|     bool preemtive; | ||||
| }; | ||||
|  | ||||
| } // namespace VideoCore | ||||
| } // namespace VideoCore | ||||
|   | ||||
| @@ -84,4 +84,4 @@ private: | ||||
|     std::vector<std::unique_ptr<DescriptorBank>> banks; | ||||
| }; | ||||
|  | ||||
| } // namespace Vulkan | ||||
| } // namespace Vulkan | ||||
|   | ||||
| @@ -66,4 +66,4 @@ BlockLinearSwizzle3DParams MakeBlockLinearSwizzle3DParams(const SwizzleParameter | ||||
|     }; | ||||
| } | ||||
|  | ||||
| } // namespace VideoCommon::Accelerated | ||||
| } // namespace VideoCommon::Accelerated | ||||
|   | ||||
| @@ -494,4 +494,4 @@ QString ConfigureRingController::AnalogToText(const Common::ParamPackage& param, | ||||
|     } | ||||
|  | ||||
|     return QObject::tr("[unknown]"); | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -12,9 +12,10 @@ | ||||
| #include <QGraphicsItem> | ||||
| #include <QLineEdit> | ||||
| #include <QMessageBox> | ||||
| #include <QSpinBox> | ||||
|  | ||||
| #include "common/settings.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/service/time/time_manager.h" | ||||
| #include "ui_configure_system.h" | ||||
| #include "yuzu/configuration/configuration_shared.h" | ||||
| #include "yuzu/configuration/configure_system.h" | ||||
| @@ -49,6 +50,11 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, | ||||
|     : Tab(group_, parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_} { | ||||
|     ui->setupUi(this); | ||||
|  | ||||
|     const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); | ||||
|     const auto current_time_s = | ||||
|         std::chrono::duration_cast<std::chrono::seconds>(posix_time).count(); | ||||
|     previous_time = current_time_s + Settings::values.custom_rtc_offset.GetValue(); | ||||
|  | ||||
|     Setup(builder); | ||||
|  | ||||
|     const auto locale_check = [this]() { | ||||
| @@ -64,13 +70,28 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     const auto update_date_offset = [this]() { | ||||
|         if (!checkbox_rtc->isChecked()) { | ||||
|             return; | ||||
|         } | ||||
|         auto offset = date_rtc_offset->value(); | ||||
|         offset += date_rtc->dateTime().toSecsSinceEpoch() - previous_time; | ||||
|         previous_time = date_rtc->dateTime().toSecsSinceEpoch(); | ||||
|         date_rtc_offset->setValue(offset); | ||||
|     }; | ||||
|     const auto update_rtc_date = [this]() { UpdateRtcTime(); }; | ||||
|  | ||||
|     connect(combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check); | ||||
|     connect(combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check); | ||||
|     connect(checkbox_rtc, qOverload<int>(&QCheckBox::stateChanged), this, update_rtc_date); | ||||
|     connect(date_rtc_offset, qOverload<int>(&QSpinBox::valueChanged), this, update_rtc_date); | ||||
|     connect(date_rtc, &QDateTimeEdit::dateTimeChanged, this, update_date_offset); | ||||
|  | ||||
|     ui->label_warn_invalid_locale->setVisible(false); | ||||
|     locale_check(); | ||||
|  | ||||
|     SetConfiguration(); | ||||
|     UpdateRtcTime(); | ||||
| } | ||||
|  | ||||
| ConfigureSystem::~ConfigureSystem() = default; | ||||
| @@ -120,14 +141,28 @@ void ConfigureSystem::Setup(const ConfigurationShared::Builder& builder) { | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         // Keep track of the region_index (and language_index) combobox to validate the selected | ||||
|         // settings | ||||
|         if (setting->Id() == Settings::values.region_index.Id()) { | ||||
|             // Keep track of the region_index (and language_index) combobox to validate the selected | ||||
|             // settings | ||||
|             combo_region = widget->combobox; | ||||
|         } else if (setting->Id() == Settings::values.language_index.Id()) { | ||||
|         } | ||||
|  | ||||
|         if (setting->Id() == Settings::values.language_index.Id()) { | ||||
|             combo_language = widget->combobox; | ||||
|         } | ||||
|  | ||||
|         if (setting->Id() == Settings::values.custom_rtc.Id()) { | ||||
|             checkbox_rtc = widget->checkbox; | ||||
|         } | ||||
|  | ||||
|         if (setting->Id() == Settings::values.custom_rtc.Id()) { | ||||
|             date_rtc = widget->date_time_edit; | ||||
|         } | ||||
|  | ||||
|         if (setting->Id() == Settings::values.custom_rtc_offset.Id()) { | ||||
|             date_rtc_offset = widget->spinbox; | ||||
|         } | ||||
|  | ||||
|         switch (setting->GetCategory()) { | ||||
|         case Settings::Category::Core: | ||||
|             core_hold.emplace(setting->Id(), widget); | ||||
| @@ -147,6 +182,19 @@ void ConfigureSystem::Setup(const ConfigurationShared::Builder& builder) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ConfigureSystem::UpdateRtcTime() { | ||||
|     const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); | ||||
|     previous_time = std::chrono::duration_cast<std::chrono::seconds>(posix_time).count(); | ||||
|     date_rtc_offset->setEnabled(checkbox_rtc->isChecked()); | ||||
|  | ||||
|     if (checkbox_rtc->isChecked()) { | ||||
|         previous_time += date_rtc_offset->value(); | ||||
|     } | ||||
|  | ||||
|     const auto date = QDateTime::fromSecsSinceEpoch(previous_time); | ||||
|     date_rtc->setDateTime(date); | ||||
| } | ||||
|  | ||||
| void ConfigureSystem::SetConfiguration() {} | ||||
|  | ||||
| void ConfigureSystem::ApplyConfiguration() { | ||||
| @@ -154,4 +202,5 @@ void ConfigureSystem::ApplyConfiguration() { | ||||
|     for (const auto& func : apply_funcs) { | ||||
|         func(powered_on); | ||||
|     } | ||||
|     UpdateRtcTime(); | ||||
| } | ||||
|   | ||||
| @@ -43,6 +43,8 @@ private: | ||||
|  | ||||
|     void Setup(const ConfigurationShared::Builder& builder); | ||||
|  | ||||
|     void UpdateRtcTime(); | ||||
|  | ||||
|     std::vector<std::function<void(bool)>> apply_funcs{}; | ||||
|  | ||||
|     std::unique_ptr<Ui::ConfigureSystem> ui; | ||||
| @@ -52,4 +54,8 @@ private: | ||||
|  | ||||
|     QComboBox* combo_region; | ||||
|     QComboBox* combo_language; | ||||
|     QCheckBox* checkbox_rtc; | ||||
|     QDateTimeEdit* date_rtc; | ||||
|     QSpinBox* date_rtc_offset; | ||||
|     u64 previous_time; | ||||
| }; | ||||
|   | ||||
| @@ -143,8 +143,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) { | ||||
|     INSERT(Settings, rng_seed, tr("RNG Seed"), QStringLiteral()); | ||||
|     INSERT(Settings, rng_seed_enabled, QStringLiteral(), QStringLiteral()); | ||||
|     INSERT(Settings, device_name, tr("Device Name"), QStringLiteral()); | ||||
|     INSERT(Settings, custom_rtc, tr("Custom RTC"), QStringLiteral()); | ||||
|     INSERT(Settings, custom_rtc, tr("Custom RTC Date:"), QStringLiteral()); | ||||
|     INSERT(Settings, custom_rtc_enabled, QStringLiteral(), QStringLiteral()); | ||||
|     INSERT(Settings, custom_rtc_offset, tr(" "), | ||||
|            QStringLiteral("The number of seconds from the current unix time")); | ||||
|     INSERT(Settings, language_index, tr("Language:"), | ||||
|            tr("Note: this can be overridden when region setting is auto-select")); | ||||
|     INSERT(Settings, region_index, tr("Region:"), QStringLiteral()); | ||||
|   | ||||
| @@ -10,4 +10,4 @@ namespace Debugger { | ||||
|  * get a real qt logging window which would work for all platforms. | ||||
|  */ | ||||
| void ToggleConsole(); | ||||
| } // namespace Debugger | ||||
| } // namespace Debugger | ||||
|   | ||||
		Reference in New Issue
	
	Block a user