mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Implement GetClockSnapshot
Needed by megaman 11
This commit is contained in:
		
							parent
							
								
									29f082775b
								
							
						
					
					
						commit
						4f78f5c0df
					
				| @ -21,7 +21,7 @@ Time::Time(std::shared_ptr<Module> time, const char* name) | ||||
|         {102, nullptr, "GetStandardUserSystemClockInitialYear"}, | ||||
|         {200, nullptr, "IsStandardNetworkSystemClockAccuracySufficient"}, | ||||
|         {300, nullptr, "CalculateMonotonicSystemClockBaseTimePoint"}, | ||||
|         {400, nullptr, "GetClockSnapshot"}, | ||||
|         {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, | ||||
|         {401, nullptr, "GetClockSnapshotFromSystemClockContext"}, | ||||
|         {500, nullptr, "CalculateStandardUserSystemClockDifferenceByUser"}, | ||||
|         {501, nullptr, "CalculateSpanBetween"}, | ||||
|  | ||||
| @ -15,6 +15,26 @@ | ||||
| 
 | ||||
| namespace Service::Time { | ||||
| 
 | ||||
| void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time, | ||||
|                      CalendarAdditionalInfo& additional_info, const TimeZoneRule& /*rule*/) { | ||||
|     std::time_t time(posix_time); | ||||
|     std::tm* tm = std::localtime(&time); | ||||
|     if (tm == nullptr) { | ||||
|         return; | ||||
|     } | ||||
|     calendar_time.year = tm->tm_year + 1900; | ||||
|     calendar_time.month = tm->tm_mon + 1; | ||||
|     calendar_time.day = tm->tm_mday; | ||||
|     calendar_time.hour = tm->tm_hour; | ||||
|     calendar_time.minute = tm->tm_min; | ||||
|     calendar_time.second = tm->tm_sec; | ||||
| 
 | ||||
|     additional_info.day_of_week = tm->tm_wday; | ||||
|     additional_info.day_of_year = tm->tm_yday; | ||||
|     std::memcpy(additional_info.name.data(), "UTC", sizeof("UTC")); | ||||
|     additional_info.utc_offset = 0; | ||||
| } | ||||
| 
 | ||||
| class ISystemClock final : public ServiceFramework<ISystemClock> { | ||||
| public: | ||||
|     ISystemClock() : ServiceFramework("ISystemClock") { | ||||
| @ -150,26 +170,6 @@ private: | ||||
|         rb.PushRaw(calendar_time); | ||||
|         rb.PushRaw(additional_info); | ||||
|     } | ||||
| 
 | ||||
|     void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time, | ||||
|                          CalendarAdditionalInfo& additional_info, const TimeZoneRule& /*rule*/) { | ||||
|         std::time_t t(posix_time); | ||||
|         std::tm* tm = std::localtime(&t); | ||||
|         if (!tm) { | ||||
|             return; | ||||
|         } | ||||
|         calendar_time.year = tm->tm_year + 1900; | ||||
|         calendar_time.month = tm->tm_mon + 1; | ||||
|         calendar_time.day = tm->tm_mday; | ||||
|         calendar_time.hour = tm->tm_hour; | ||||
|         calendar_time.minute = tm->tm_min; | ||||
|         calendar_time.second = tm->tm_sec; | ||||
| 
 | ||||
|         additional_info.day_of_week = tm->tm_wday; | ||||
|         additional_info.day_of_year = tm->tm_yday; | ||||
|         std::memcpy(additional_info.name.data(), "UTC", sizeof("UTC")); | ||||
|         additional_info.utc_offset = 0; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { | ||||
| @ -207,6 +207,55 @@ void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& c | ||||
|     LOG_DEBUG(Service_Time, "called"); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_Time, "called"); | ||||
| 
 | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     auto unknown_u8 = rp.PopRaw<u8>(); | ||||
| 
 | ||||
|     ClockSnapshot clock_snapshot{}; | ||||
| 
 | ||||
|     const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>( | ||||
|                                    std::chrono::system_clock::now().time_since_epoch()) | ||||
|                                    .count()}; | ||||
|     CalendarTime calendar_time{}; | ||||
|     std::time_t time(time_since_epoch); | ||||
|     std::tm* tm = std::localtime(&time); | ||||
|     if (tm == nullptr) { | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultCode(-1)); // TODO(ogniK): Find appropriate error code
 | ||||
|         return; | ||||
|     } | ||||
|     SteadyClockTimePoint steady_clock_time_point{CoreTiming::cyclesToMs(CoreTiming::GetTicks()) / | ||||
|                                                  1000}; | ||||
| 
 | ||||
|     LocationName location_name{"UTC"}; | ||||
|     calendar_time.year = tm->tm_year + 1900; | ||||
|     calendar_time.month = tm->tm_mon + 1; | ||||
|     calendar_time.day = tm->tm_mday; | ||||
|     calendar_time.hour = tm->tm_hour; | ||||
|     calendar_time.minute = tm->tm_min; | ||||
|     calendar_time.second = tm->tm_sec; | ||||
|     clock_snapshot.system_posix_time = time_since_epoch; | ||||
|     clock_snapshot.network_posix_time = time_since_epoch; | ||||
|     clock_snapshot.system_calendar_time = calendar_time; | ||||
|     clock_snapshot.network_calendar_time = calendar_time; | ||||
| 
 | ||||
|     CalendarAdditionalInfo additional_info{}; | ||||
|     PosixToCalendar(time_since_epoch, calendar_time, additional_info, {}); | ||||
| 
 | ||||
|     clock_snapshot.system_calendar_info = additional_info; | ||||
|     clock_snapshot.network_calendar_info = additional_info; | ||||
| 
 | ||||
|     clock_snapshot.steady_clock_timepoint = steady_clock_time_point; | ||||
|     clock_snapshot.location_name = location_name; | ||||
|     clock_snapshot.clock_auto_adjustment_enabled = 1; | ||||
|     clock_snapshot.ipc_u8 = unknown_u8; | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     ctx.WriteBuffer(&clock_snapshot, sizeof(ClockSnapshot)); | ||||
| } | ||||
| 
 | ||||
| Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) | ||||
|     : ServiceFramework(name), time(std::move(time)) {} | ||||
| 
 | ||||
|  | ||||
| @ -53,6 +53,23 @@ struct SystemClockContext { | ||||
| static_assert(sizeof(SystemClockContext) == 0x20, | ||||
|               "SystemClockContext structure has incorrect size"); | ||||
| 
 | ||||
| struct ClockSnapshot { | ||||
|     SystemClockContext user_clock_context; | ||||
|     SystemClockContext network_clock_context; | ||||
|     s64_le system_posix_time; | ||||
|     s64_le network_posix_time; | ||||
|     CalendarTime system_calendar_time; | ||||
|     CalendarTime network_calendar_time; | ||||
|     CalendarAdditionalInfo system_calendar_info; | ||||
|     CalendarAdditionalInfo network_calendar_info; | ||||
|     SteadyClockTimePoint steady_clock_timepoint; | ||||
|     LocationName location_name; | ||||
|     u8 clock_auto_adjustment_enabled; | ||||
|     u8 ipc_u8; | ||||
|     INSERT_PADDING_BYTES(2); | ||||
| }; | ||||
| static_assert(sizeof(ClockSnapshot) == 0xd0, "ClockSnapshot is an invalid size"); | ||||
| 
 | ||||
| class Module final { | ||||
| public: | ||||
|     class Interface : public ServiceFramework<Interface> { | ||||
| @ -65,6 +82,7 @@ public: | ||||
|         void GetStandardSteadyClock(Kernel::HLERequestContext& ctx); | ||||
|         void GetTimeZoneService(Kernel::HLERequestContext& ctx); | ||||
|         void GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx); | ||||
|         void GetClockSnapshot(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     protected: | ||||
|         std::shared_ptr<Module> time; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 David Marcec
						David Marcec