service: time: Update current time with changes to RTC setting.
- This can be used to advance time, e.g. for Pokemon Sword/Shield pokejobs.
This commit is contained in:
parent
4c348f4069
commit
62c6c9f6a6
|
@ -40,6 +40,7 @@
|
||||||
#include "core/hle/service/lm/manager.h"
|
#include "core/hle/service/lm/manager.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
|
#include "core/hle/service/time/time_manager.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/memory/cheat_engine.h"
|
#include "core/memory/cheat_engine.h"
|
||||||
|
@ -121,7 +122,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
||||||
struct System::Impl {
|
struct System::Impl {
|
||||||
explicit Impl(System& system)
|
explicit Impl(System& system)
|
||||||
: kernel{system}, fs_controller{system}, memory{system},
|
: kernel{system}, fs_controller{system}, memory{system},
|
||||||
cpu_manager{system}, reporter{system}, applet_manager{system} {}
|
cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
|
||||||
|
|
||||||
ResultStatus Run() {
|
ResultStatus Run() {
|
||||||
status = ResultStatus::Success;
|
status = ResultStatus::Success;
|
||||||
|
@ -189,6 +190,9 @@ struct System::Impl {
|
||||||
return ResultStatus::ErrorVideoCore;
|
return ResultStatus::ErrorVideoCore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize time manager, which must happen after kernel is created
|
||||||
|
time_manager.Initialize();
|
||||||
|
|
||||||
is_powered_on = true;
|
is_powered_on = true;
|
||||||
exit_lock = false;
|
exit_lock = false;
|
||||||
|
|
||||||
|
@ -387,6 +391,7 @@ struct System::Impl {
|
||||||
/// Service State
|
/// Service State
|
||||||
Service::Glue::ARPManager arp_manager;
|
Service::Glue::ARPManager arp_manager;
|
||||||
Service::LM::Manager lm_manager{reporter};
|
Service::LM::Manager lm_manager{reporter};
|
||||||
|
Service::Time::TimeManager time_manager;
|
||||||
|
|
||||||
/// Service manager
|
/// Service manager
|
||||||
std::shared_ptr<Service::SM::ServiceManager> service_manager;
|
std::shared_ptr<Service::SM::ServiceManager> service_manager;
|
||||||
|
@ -717,6 +722,14 @@ const Service::LM::Manager& System::GetLogManager() const {
|
||||||
return impl->lm_manager;
|
return impl->lm_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Service::Time::TimeManager& System::GetTimeManager() {
|
||||||
|
return impl->time_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Service::Time::TimeManager& System::GetTimeManager() const {
|
||||||
|
return impl->time_manager;
|
||||||
|
}
|
||||||
|
|
||||||
void System::SetExitLock(bool locked) {
|
void System::SetExitLock(bool locked) {
|
||||||
impl->exit_lock = locked;
|
impl->exit_lock = locked;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,10 @@ namespace SM {
|
||||||
class ServiceManager;
|
class ServiceManager;
|
||||||
} // namespace SM
|
} // namespace SM
|
||||||
|
|
||||||
|
namespace Time {
|
||||||
|
class TimeManager;
|
||||||
|
} // namespace Time
|
||||||
|
|
||||||
} // namespace Service
|
} // namespace Service
|
||||||
|
|
||||||
namespace Tegra {
|
namespace Tegra {
|
||||||
|
@ -361,6 +365,10 @@ public:
|
||||||
|
|
||||||
const Service::LM::Manager& GetLogManager() const;
|
const Service::LM::Manager& GetLogManager() const;
|
||||||
|
|
||||||
|
Service::Time::TimeManager& GetTimeManager();
|
||||||
|
|
||||||
|
const Service::Time::TimeManager& GetTimeManager() const;
|
||||||
|
|
||||||
void SetExitLock(bool locked);
|
void SetExitLock(bool locked);
|
||||||
|
|
||||||
bool GetExitLock() const;
|
bool GetExitLock() const;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
#include "core/hle/kernel/client_session.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/scheduler.h"
|
#include "core/hle/kernel/scheduler.h"
|
||||||
#include "core/hle/service/time/interface.h"
|
#include "core/hle/service/time/interface.h"
|
||||||
#include "core/hle/service/time/time.h"
|
#include "core/hle/service/time/time.h"
|
||||||
|
@ -125,7 +126,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal(
|
||||||
Kernel::Thread* thread, Clock::SystemClockContext user_context,
|
Kernel::Thread* thread, Clock::SystemClockContext user_context,
|
||||||
Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) {
|
Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) {
|
||||||
|
|
||||||
auto& time_manager{module->GetTimeManager()};
|
auto& time_manager{system.GetTimeManager()};
|
||||||
|
|
||||||
clock_snapshot.is_automatic_correction_enabled =
|
clock_snapshot.is_automatic_correction_enabled =
|
||||||
time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled();
|
time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled();
|
||||||
|
@ -182,7 +183,7 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct
|
||||||
LOG_DEBUG(Service_Time, "called");
|
LOG_DEBUG(Service_Time, "called");
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardUserSystemClockCore(),
|
rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardUserSystemClockCore(),
|
||||||
system);
|
system);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +191,7 @@ void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext&
|
||||||
LOG_DEBUG(Service_Time, "called");
|
LOG_DEBUG(Service_Time, "called");
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardNetworkSystemClockCore(),
|
rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardNetworkSystemClockCore(),
|
||||||
system);
|
system);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,29 +199,28 @@ void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Time, "called");
|
LOG_DEBUG(Service_Time, "called");
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushIpcInterface<ISteadyClock>(module->GetTimeManager().GetStandardSteadyClockCore(),
|
rb.PushIpcInterface<ISteadyClock>(system.GetTimeManager().GetStandardSteadyClockCore(), system);
|
||||||
system);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Time, "called");
|
LOG_DEBUG(Service_Time, "called");
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushIpcInterface<ITimeZoneService>(module->GetTimeManager().GetTimeZoneContentManager());
|
rb.PushIpcInterface<ITimeZoneService>(system.GetTimeManager().GetTimeZoneContentManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Time, "called");
|
LOG_DEBUG(Service_Time, "called");
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardLocalSystemClockCore(),
|
rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardLocalSystemClockCore(),
|
||||||
system);
|
system);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(
|
void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(
|
||||||
Kernel::HLERequestContext& ctx) {
|
Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Time, "called");
|
LOG_DEBUG(Service_Time, "called");
|
||||||
auto& clock_core{module->GetTimeManager().GetStandardNetworkSystemClockCore()};
|
auto& clock_core{system.GetTimeManager().GetStandardNetworkSystemClockCore()};
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system));
|
rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system));
|
||||||
|
@ -229,7 +229,7 @@ void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(
|
||||||
void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Time, "called");
|
LOG_DEBUG(Service_Time, "called");
|
||||||
|
|
||||||
auto& steady_clock_core{module->GetTimeManager().GetStandardSteadyClockCore()};
|
auto& steady_clock_core{system.GetTimeManager().GetStandardSteadyClockCore()};
|
||||||
if (!steady_clock_core.IsInitialized()) {
|
if (!steady_clock_core.IsInitialized()) {
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERROR_UNINITIALIZED_CLOCK);
|
rb.Push(ERROR_UNINITIALIZED_CLOCK);
|
||||||
|
@ -262,8 +262,8 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
Clock::SystemClockContext user_context{};
|
Clock::SystemClockContext user_context{};
|
||||||
if (const ResultCode result{
|
if (const ResultCode result{
|
||||||
module->GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(
|
system.GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(system,
|
||||||
system, user_context)};
|
user_context)};
|
||||||
result.IsError()) {
|
result.IsError()) {
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(result);
|
rb.Push(result);
|
||||||
|
@ -271,7 +271,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
Clock::SystemClockContext network_context{};
|
Clock::SystemClockContext network_context{};
|
||||||
if (const ResultCode result{
|
if (const ResultCode result{
|
||||||
module->GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext(
|
system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext(
|
||||||
system, network_context)};
|
system, network_context)};
|
||||||
result.IsError()) {
|
result.IsError()) {
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
@ -372,7 +372,7 @@ void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& c
|
||||||
LOG_DEBUG(Service_Time, "called");
|
LOG_DEBUG(Service_Time, "called");
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushCopyObjects(module->GetTimeManager().GetSharedMemory().GetSharedMemoryHolder());
|
rb.PushCopyObjects(SharedFrom(&system.Kernel().GetTimeSharedMem()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name)
|
Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name)
|
||||||
|
@ -381,7 +381,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& syste
|
||||||
Module::Interface::~Interface() = default;
|
Module::Interface::~Interface() = default;
|
||||||
|
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
auto module{std::make_shared<Module>(system)};
|
auto module{std::make_shared<Module>()};
|
||||||
std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager());
|
std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager());
|
||||||
std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager());
|
std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager());
|
||||||
std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager());
|
std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager());
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Service::Time {
|
||||||
|
|
||||||
class Module final {
|
class Module final {
|
||||||
public:
|
public:
|
||||||
Module(Core::System& system) : time_manager{system} {}
|
Module() = default;
|
||||||
|
|
||||||
class Interface : public ServiceFramework<Interface> {
|
class Interface : public ServiceFramework<Interface> {
|
||||||
public:
|
public:
|
||||||
|
@ -46,13 +46,6 @@ public:
|
||||||
std::shared_ptr<Module> module;
|
std::shared_ptr<Module> module;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
TimeManager& GetTimeManager() {
|
|
||||||
return time_manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
TimeManager time_manager;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Registers all Time services with the specified service manager.
|
/// Registers all Time services with the specified service manager.
|
||||||
|
|
|
@ -22,7 +22,277 @@ static std::chrono::seconds GetSecondsSinceEpoch() {
|
||||||
Settings::values.custom_rtc_differential;
|
Settings::values.custom_rtc_differential;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s64 GetExternalTimeZoneOffset() {
|
static s64 GetExternalRtcValue() {
|
||||||
|
return GetSecondsSinceEpoch().count() + TimeManager::GetExternalTimeZoneOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TimeManager::Impl final {
|
||||||
|
explicit Impl(Core::System& system)
|
||||||
|
: shared_memory{system}, standard_local_system_clock_core{standard_steady_clock_core},
|
||||||
|
standard_network_system_clock_core{standard_steady_clock_core},
|
||||||
|
standard_user_system_clock_core{standard_local_system_clock_core,
|
||||||
|
standard_network_system_clock_core, system},
|
||||||
|
ephemeral_network_system_clock_core{tick_based_steady_clock_core},
|
||||||
|
local_system_clock_context_writer{
|
||||||
|
std::make_shared<Clock::LocalSystemClockContextWriter>(shared_memory)},
|
||||||
|
network_system_clock_context_writer{
|
||||||
|
std::make_shared<Clock::NetworkSystemClockContextWriter>(shared_memory)},
|
||||||
|
ephemeral_network_system_clock_context_writer{
|
||||||
|
std::make_shared<Clock::EphemeralNetworkSystemClockContextWriter>()},
|
||||||
|
time_zone_content_manager{system} {
|
||||||
|
|
||||||
|
const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())};
|
||||||
|
SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {});
|
||||||
|
SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds());
|
||||||
|
SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy);
|
||||||
|
SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom());
|
||||||
|
SetupEphemeralNetworkSystemClock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~Impl() = default;
|
||||||
|
|
||||||
|
Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() {
|
||||||
|
return standard_steady_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const {
|
||||||
|
return standard_steady_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() {
|
||||||
|
return standard_local_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const {
|
||||||
|
return standard_local_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() {
|
||||||
|
return standard_network_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const {
|
||||||
|
return standard_network_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() {
|
||||||
|
return standard_user_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const {
|
||||||
|
return standard_user_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() {
|
||||||
|
return time_zone_content_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const {
|
||||||
|
return time_zone_content_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedMemory& GetSharedMemory() {
|
||||||
|
return shared_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SharedMemory& GetSharedMemory() const {
|
||||||
|
return shared_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupTimeZoneManager(std::string location_name,
|
||||||
|
Clock::SteadyClockTimePoint time_zone_updated_time_point,
|
||||||
|
std::size_t total_location_name_count, u128 time_zone_rule_version,
|
||||||
|
FileSys::VirtualFile& vfs_file) {
|
||||||
|
if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule(
|
||||||
|
location_name, vfs_file) != RESULT_SUCCESS) {
|
||||||
|
UNREACHABLE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_zone_content_manager.GetTimeZoneManager().SetUpdatedTime(time_zone_updated_time_point);
|
||||||
|
time_zone_content_manager.GetTimeZoneManager().SetTotalLocationNameCount(
|
||||||
|
total_location_name_count);
|
||||||
|
time_zone_content_manager.GetTimeZoneManager().SetTimeZoneRuleVersion(
|
||||||
|
time_zone_rule_version);
|
||||||
|
time_zone_content_manager.GetTimeZoneManager().MarkAsInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
static s64 GetExternalTimeZoneOffset() {
|
||||||
|
// With "auto" timezone setting, we use the external system's timezone offset
|
||||||
|
if (Settings::GetTimeZoneString() == "auto") {
|
||||||
|
return Common::TimeZone::GetCurrentOffsetSeconds().count();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id,
|
||||||
|
Clock::TimeSpanType setup_value,
|
||||||
|
Clock::TimeSpanType internal_offset, bool is_rtc_reset_detected) {
|
||||||
|
standard_steady_clock_core.SetClockSourceId(clock_source_id);
|
||||||
|
standard_steady_clock_core.SetSetupValue(setup_value);
|
||||||
|
standard_steady_clock_core.SetInternalOffset(internal_offset);
|
||||||
|
standard_steady_clock_core.MarkAsInitialized();
|
||||||
|
|
||||||
|
const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system)};
|
||||||
|
shared_memory.SetupStandardSteadyClock(system, clock_source_id, current_time_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupStandardLocalSystemClock(Core::System& system,
|
||||||
|
Clock::SystemClockContext clock_context, s64 posix_time) {
|
||||||
|
standard_local_system_clock_core.SetUpdateCallbackInstance(
|
||||||
|
local_system_clock_context_writer);
|
||||||
|
|
||||||
|
const auto current_time_point{
|
||||||
|
standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system)};
|
||||||
|
if (current_time_point.clock_source_id == clock_context.steady_time_point.clock_source_id) {
|
||||||
|
standard_local_system_clock_core.SetSystemClockContext(clock_context);
|
||||||
|
} else {
|
||||||
|
if (standard_local_system_clock_core.SetCurrentTime(system, posix_time) !=
|
||||||
|
RESULT_SUCCESS) {
|
||||||
|
UNREACHABLE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
standard_local_system_clock_core.MarkAsInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context,
|
||||||
|
Clock::TimeSpanType sufficient_accuracy) {
|
||||||
|
standard_network_system_clock_core.SetUpdateCallbackInstance(
|
||||||
|
network_system_clock_context_writer);
|
||||||
|
|
||||||
|
if (standard_network_system_clock_core.SetSystemClockContext(clock_context) !=
|
||||||
|
RESULT_SUCCESS) {
|
||||||
|
UNREACHABLE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
standard_network_system_clock_core.SetStandardNetworkClockSufficientAccuracy(
|
||||||
|
sufficient_accuracy);
|
||||||
|
standard_network_system_clock_core.MarkAsInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupStandardUserSystemClock(Core::System& system, bool is_automatic_correction_enabled,
|
||||||
|
Clock::SteadyClockTimePoint steady_clock_time_point) {
|
||||||
|
if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled(
|
||||||
|
system, is_automatic_correction_enabled) != RESULT_SUCCESS) {
|
||||||
|
UNREACHABLE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
standard_user_system_clock_core.SetAutomaticCorrectionUpdatedTime(steady_clock_time_point);
|
||||||
|
standard_user_system_clock_core.MarkAsInitialized();
|
||||||
|
shared_memory.SetAutomaticCorrectionEnabled(is_automatic_correction_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupEphemeralNetworkSystemClock() {
|
||||||
|
ephemeral_network_system_clock_core.SetUpdateCallbackInstance(
|
||||||
|
ephemeral_network_system_clock_context_writer);
|
||||||
|
ephemeral_network_system_clock_core.MarkAsInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateLocalSystemClockTime(Core::System& system, s64 posix_time) {
|
||||||
|
const auto timespan{Service::Time::Clock::TimeSpanType::FromSeconds(posix_time)};
|
||||||
|
if (GetStandardLocalSystemClockCore()
|
||||||
|
.SetCurrentTime(system, timespan.ToSeconds())
|
||||||
|
.IsError()) {
|
||||||
|
UNREACHABLE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedMemory shared_memory;
|
||||||
|
|
||||||
|
Clock::StandardSteadyClockCore standard_steady_clock_core;
|
||||||
|
Clock::TickBasedSteadyClockCore tick_based_steady_clock_core;
|
||||||
|
Clock::StandardLocalSystemClockCore standard_local_system_clock_core;
|
||||||
|
Clock::StandardNetworkSystemClockCore standard_network_system_clock_core;
|
||||||
|
Clock::StandardUserSystemClockCore standard_user_system_clock_core;
|
||||||
|
Clock::EphemeralNetworkSystemClockCore ephemeral_network_system_clock_core;
|
||||||
|
|
||||||
|
std::shared_ptr<Clock::LocalSystemClockContextWriter> local_system_clock_context_writer;
|
||||||
|
std::shared_ptr<Clock::NetworkSystemClockContextWriter> network_system_clock_context_writer;
|
||||||
|
std::shared_ptr<Clock::EphemeralNetworkSystemClockContextWriter>
|
||||||
|
ephemeral_network_system_clock_context_writer;
|
||||||
|
|
||||||
|
TimeZone::TimeZoneContentManager time_zone_content_manager;
|
||||||
|
};
|
||||||
|
|
||||||
|
TimeManager::TimeManager(Core::System& system) : system{system} {}
|
||||||
|
|
||||||
|
TimeManager::~TimeManager() = default;
|
||||||
|
|
||||||
|
void TimeManager::Initialize() {
|
||||||
|
impl = std::make_unique<Impl>(system);
|
||||||
|
|
||||||
|
// Time zones can only be initialized after impl is valid
|
||||||
|
impl->time_zone_content_manager.Initialize(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Clock::StandardSteadyClockCore& TimeManager::GetStandardSteadyClockCore() {
|
||||||
|
return impl->standard_steady_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Clock::StandardSteadyClockCore& TimeManager::GetStandardSteadyClockCore() const {
|
||||||
|
return impl->standard_steady_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clock::StandardLocalSystemClockCore& TimeManager::GetStandardLocalSystemClockCore() {
|
||||||
|
return impl->standard_local_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Clock::StandardLocalSystemClockCore& TimeManager::GetStandardLocalSystemClockCore() const {
|
||||||
|
return impl->standard_local_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clock::StandardNetworkSystemClockCore& TimeManager::GetStandardNetworkSystemClockCore() {
|
||||||
|
return impl->standard_network_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Clock::StandardNetworkSystemClockCore& TimeManager::GetStandardNetworkSystemClockCore()
|
||||||
|
const {
|
||||||
|
return impl->standard_network_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clock::StandardUserSystemClockCore& TimeManager::GetStandardUserSystemClockCore() {
|
||||||
|
return impl->standard_user_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Clock::StandardUserSystemClockCore& TimeManager::GetStandardUserSystemClockCore() const {
|
||||||
|
return impl->standard_user_system_clock_core;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeZone::TimeZoneContentManager& TimeManager::GetTimeZoneContentManager() {
|
||||||
|
return impl->time_zone_content_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TimeZone::TimeZoneContentManager& TimeManager::GetTimeZoneContentManager() const {
|
||||||
|
return impl->time_zone_content_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedMemory& TimeManager::GetSharedMemory() {
|
||||||
|
return impl->shared_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SharedMemory& TimeManager::GetSharedMemory() const {
|
||||||
|
return impl->shared_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeManager::UpdateLocalSystemClockTime(s64 posix_time) {
|
||||||
|
impl->UpdateLocalSystemClockTime(system, posix_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeManager::SetupTimeZoneManager(std::string location_name,
|
||||||
|
Clock::SteadyClockTimePoint time_zone_updated_time_point,
|
||||||
|
std::size_t total_location_name_count,
|
||||||
|
u128 time_zone_rule_version,
|
||||||
|
FileSys::VirtualFile& vfs_file) {
|
||||||
|
impl->SetupTimeZoneManager(location_name, time_zone_updated_time_point,
|
||||||
|
total_location_name_count, time_zone_rule_version, vfs_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ s64 TimeManager::GetExternalTimeZoneOffset() {
|
||||||
// With "auto" timezone setting, we use the external system's timezone offset
|
// With "auto" timezone setting, we use the external system's timezone offset
|
||||||
if (Settings::GetTimeZoneString() == "auto") {
|
if (Settings::GetTimeZoneString() == "auto") {
|
||||||
return Common::TimeZone::GetCurrentOffsetSeconds().count();
|
return Common::TimeZone::GetCurrentOffsetSeconds().count();
|
||||||
|
@ -30,117 +300,4 @@ static s64 GetExternalTimeZoneOffset() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s64 GetExternalRtcValue() {
|
|
||||||
return GetSecondsSinceEpoch().count() + GetExternalTimeZoneOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeManager::TimeManager(Core::System& system)
|
|
||||||
: shared_memory{system}, standard_local_system_clock_core{standard_steady_clock_core},
|
|
||||||
standard_network_system_clock_core{standard_steady_clock_core},
|
|
||||||
standard_user_system_clock_core{standard_local_system_clock_core,
|
|
||||||
standard_network_system_clock_core, system},
|
|
||||||
ephemeral_network_system_clock_core{tick_based_steady_clock_core},
|
|
||||||
local_system_clock_context_writer{
|
|
||||||
std::make_shared<Clock::LocalSystemClockContextWriter>(shared_memory)},
|
|
||||||
network_system_clock_context_writer{
|
|
||||||
std::make_shared<Clock::NetworkSystemClockContextWriter>(shared_memory)},
|
|
||||||
ephemeral_network_system_clock_context_writer{
|
|
||||||
std::make_shared<Clock::EphemeralNetworkSystemClockContextWriter>()},
|
|
||||||
time_zone_content_manager{*this, system} {
|
|
||||||
|
|
||||||
const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())};
|
|
||||||
SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {});
|
|
||||||
SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds());
|
|
||||||
SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy);
|
|
||||||
SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom());
|
|
||||||
SetupEphemeralNetworkSystemClock();
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeManager::~TimeManager() = default;
|
|
||||||
|
|
||||||
void TimeManager::SetupTimeZoneManager(std::string location_name,
|
|
||||||
Clock::SteadyClockTimePoint time_zone_updated_time_point,
|
|
||||||
std::size_t total_location_name_count,
|
|
||||||
u128 time_zone_rule_version,
|
|
||||||
FileSys::VirtualFile& vfs_file) {
|
|
||||||
if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule(
|
|
||||||
location_name, vfs_file) != RESULT_SUCCESS) {
|
|
||||||
UNREACHABLE();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_zone_content_manager.GetTimeZoneManager().SetUpdatedTime(time_zone_updated_time_point);
|
|
||||||
time_zone_content_manager.GetTimeZoneManager().SetTotalLocationNameCount(
|
|
||||||
total_location_name_count);
|
|
||||||
time_zone_content_manager.GetTimeZoneManager().SetTimeZoneRuleVersion(time_zone_rule_version);
|
|
||||||
time_zone_content_manager.GetTimeZoneManager().MarkAsInitialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeManager::SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id,
|
|
||||||
Clock::TimeSpanType setup_value,
|
|
||||||
Clock::TimeSpanType internal_offset,
|
|
||||||
bool is_rtc_reset_detected) {
|
|
||||||
standard_steady_clock_core.SetClockSourceId(clock_source_id);
|
|
||||||
standard_steady_clock_core.SetSetupValue(setup_value);
|
|
||||||
standard_steady_clock_core.SetInternalOffset(internal_offset);
|
|
||||||
standard_steady_clock_core.MarkAsInitialized();
|
|
||||||
|
|
||||||
const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system)};
|
|
||||||
shared_memory.SetupStandardSteadyClock(system, clock_source_id, current_time_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeManager::SetupStandardLocalSystemClock(Core::System& system,
|
|
||||||
Clock::SystemClockContext clock_context,
|
|
||||||
s64 posix_time) {
|
|
||||||
standard_local_system_clock_core.SetUpdateCallbackInstance(local_system_clock_context_writer);
|
|
||||||
|
|
||||||
const auto current_time_point{
|
|
||||||
standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system)};
|
|
||||||
if (current_time_point.clock_source_id == clock_context.steady_time_point.clock_source_id) {
|
|
||||||
standard_local_system_clock_core.SetSystemClockContext(clock_context);
|
|
||||||
} else {
|
|
||||||
if (standard_local_system_clock_core.SetCurrentTime(system, posix_time) != RESULT_SUCCESS) {
|
|
||||||
UNREACHABLE();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
standard_local_system_clock_core.MarkAsInitialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeManager::SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context,
|
|
||||||
Clock::TimeSpanType sufficient_accuracy) {
|
|
||||||
standard_network_system_clock_core.SetUpdateCallbackInstance(
|
|
||||||
network_system_clock_context_writer);
|
|
||||||
|
|
||||||
if (standard_network_system_clock_core.SetSystemClockContext(clock_context) != RESULT_SUCCESS) {
|
|
||||||
UNREACHABLE();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
standard_network_system_clock_core.SetStandardNetworkClockSufficientAccuracy(
|
|
||||||
sufficient_accuracy);
|
|
||||||
standard_network_system_clock_core.MarkAsInitialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeManager::SetupStandardUserSystemClock(
|
|
||||||
Core::System& system, bool is_automatic_correction_enabled,
|
|
||||||
Clock::SteadyClockTimePoint steady_clock_time_point) {
|
|
||||||
if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled(
|
|
||||||
system, is_automatic_correction_enabled) != RESULT_SUCCESS) {
|
|
||||||
UNREACHABLE();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
standard_user_system_clock_core.SetAutomaticCorrectionUpdatedTime(steady_clock_time_point);
|
|
||||||
standard_user_system_clock_core.MarkAsInitialized();
|
|
||||||
shared_memory.SetAutomaticCorrectionEnabled(is_automatic_correction_enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeManager::SetupEphemeralNetworkSystemClock() {
|
|
||||||
ephemeral_network_system_clock_core.SetUpdateCallbackInstance(
|
|
||||||
ephemeral_network_system_clock_context_writer);
|
|
||||||
ephemeral_network_system_clock_core.MarkAsInitialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::Time
|
} // namespace Service::Time
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/time_zone.h"
|
||||||
#include "core/file_sys/vfs_types.h"
|
#include "core/file_sys/vfs_types.h"
|
||||||
#include "core/hle/service/time/clock_types.h"
|
#include "core/hle/service/time/clock_types.h"
|
||||||
#include "core/hle/service/time/ephemeral_network_system_clock_core.h"
|
#include "core/hle/service/time/ephemeral_network_system_clock_core.h"
|
||||||
|
@ -32,86 +33,46 @@ public:
|
||||||
explicit TimeManager(Core::System& system);
|
explicit TimeManager(Core::System& system);
|
||||||
~TimeManager();
|
~TimeManager();
|
||||||
|
|
||||||
Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() {
|
void Initialize();
|
||||||
return standard_steady_clock_core;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const {
|
Clock::StandardSteadyClockCore& GetStandardSteadyClockCore();
|
||||||
return standard_steady_clock_core;
|
|
||||||
}
|
|
||||||
|
|
||||||
Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() {
|
const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const;
|
||||||
return standard_local_system_clock_core;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const {
|
Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore();
|
||||||
return standard_local_system_clock_core;
|
|
||||||
}
|
|
||||||
|
|
||||||
Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() {
|
const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const;
|
||||||
return standard_network_system_clock_core;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const {
|
Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore();
|
||||||
return standard_network_system_clock_core;
|
|
||||||
}
|
|
||||||
|
|
||||||
Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() {
|
const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const;
|
||||||
return standard_user_system_clock_core;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const {
|
Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore();
|
||||||
return standard_user_system_clock_core;
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() {
|
const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const;
|
||||||
return time_zone_content_manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const {
|
TimeZone::TimeZoneContentManager& GetTimeZoneContentManager();
|
||||||
return time_zone_content_manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedMemory& GetSharedMemory() {
|
const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const;
|
||||||
return shared_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SharedMemory& GetSharedMemory() const {
|
void UpdateLocalSystemClockTime(s64 posix_time);
|
||||||
return shared_memory;
|
|
||||||
}
|
SharedMemory& GetSharedMemory();
|
||||||
|
|
||||||
|
const SharedMemory& GetSharedMemory() const;
|
||||||
|
|
||||||
void SetupTimeZoneManager(std::string location_name,
|
void SetupTimeZoneManager(std::string location_name,
|
||||||
Clock::SteadyClockTimePoint time_zone_updated_time_point,
|
Clock::SteadyClockTimePoint time_zone_updated_time_point,
|
||||||
std::size_t total_location_name_count, u128 time_zone_rule_version,
|
std::size_t total_location_name_count, u128 time_zone_rule_version,
|
||||||
FileSys::VirtualFile& vfs_file);
|
FileSys::VirtualFile& vfs_file);
|
||||||
|
|
||||||
|
static s64 GetExternalTimeZoneOffset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id,
|
Core::System& system;
|
||||||
Clock::TimeSpanType setup_value,
|
|
||||||
Clock::TimeSpanType internal_offset, bool is_rtc_reset_detected);
|
|
||||||
void SetupStandardLocalSystemClock(Core::System& system,
|
|
||||||
Clock::SystemClockContext clock_context, s64 posix_time);
|
|
||||||
void SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context,
|
|
||||||
Clock::TimeSpanType sufficient_accuracy);
|
|
||||||
void SetupStandardUserSystemClock(Core::System& system, bool is_automatic_correction_enabled,
|
|
||||||
Clock::SteadyClockTimePoint steady_clock_time_point);
|
|
||||||
void SetupEphemeralNetworkSystemClock();
|
|
||||||
|
|
||||||
SharedMemory shared_memory;
|
struct Impl;
|
||||||
|
std::unique_ptr<Impl> impl;
|
||||||
Clock::StandardSteadyClockCore standard_steady_clock_core;
|
|
||||||
Clock::TickBasedSteadyClockCore tick_based_steady_clock_core;
|
|
||||||
Clock::StandardLocalSystemClockCore standard_local_system_clock_core;
|
|
||||||
Clock::StandardNetworkSystemClockCore standard_network_system_clock_core;
|
|
||||||
Clock::StandardUserSystemClockCore standard_user_system_clock_core;
|
|
||||||
Clock::EphemeralNetworkSystemClockCore ephemeral_network_system_clock_core;
|
|
||||||
|
|
||||||
std::shared_ptr<Clock::LocalSystemClockContextWriter> local_system_clock_context_writer;
|
|
||||||
std::shared_ptr<Clock::NetworkSystemClockContextWriter> network_system_clock_context_writer;
|
|
||||||
std::shared_ptr<Clock::EphemeralNetworkSystemClockContextWriter>
|
|
||||||
ephemeral_network_system_clock_context_writer;
|
|
||||||
|
|
||||||
TimeZone::TimeZoneContentManager time_zone_content_manager;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::Time
|
} // namespace Service::Time
|
||||||
|
|
|
@ -68,9 +68,10 @@ static std::vector<std::string> BuildLocationNameCache(Core::System& system) {
|
||||||
return location_name_cache;
|
return location_name_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeZoneContentManager::TimeZoneContentManager(TimeManager& time_manager, Core::System& system)
|
TimeZoneContentManager::TimeZoneContentManager(Core::System& system)
|
||||||
: system{system}, location_name_cache{BuildLocationNameCache(system)} {
|
: system{system}, location_name_cache{BuildLocationNameCache(system)} {}
|
||||||
|
|
||||||
|
void TimeZoneContentManager::Initialize(TimeManager& time_manager) {
|
||||||
std::string location_name;
|
std::string location_name;
|
||||||
const auto timezone_setting = Settings::GetTimeZoneString();
|
const auto timezone_setting = Settings::GetTimeZoneString();
|
||||||
if (timezone_setting == "auto" || timezone_setting == "default") {
|
if (timezone_setting == "auto" || timezone_setting == "default") {
|
||||||
|
|
|
@ -21,7 +21,9 @@ namespace Service::Time::TimeZone {
|
||||||
|
|
||||||
class TimeZoneContentManager final {
|
class TimeZoneContentManager final {
|
||||||
public:
|
public:
|
||||||
TimeZoneContentManager(TimeManager& time_manager, Core::System& system);
|
TimeZoneContentManager(Core::System& system);
|
||||||
|
|
||||||
|
void Initialize(TimeManager& time_manager);
|
||||||
|
|
||||||
TimeZoneManager& GetTimeZoneManager() {
|
TimeZoneManager& GetTimeZoneManager() {
|
||||||
return time_zone_manager;
|
return time_zone_manager;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/hle/service/time/time.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "ui_configure_system.h"
|
#include "ui_configure_system.h"
|
||||||
#include "yuzu/configuration/configuration_shared.h"
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
|
@ -104,6 +105,22 @@ void ConfigureSystem::SetConfiguration() {
|
||||||
void ConfigureSystem::ReadSystemSettings() {}
|
void ConfigureSystem::ReadSystemSettings() {}
|
||||||
|
|
||||||
void ConfigureSystem::ApplyConfiguration() {
|
void ConfigureSystem::ApplyConfiguration() {
|
||||||
|
// Allow setting custom RTC even if system is powered on, to allow in-game time to be fast
|
||||||
|
// forwared
|
||||||
|
if (Settings::values.custom_rtc.UsingGlobal()) {
|
||||||
|
if (ui->custom_rtc_checkbox->isChecked()) {
|
||||||
|
Settings::values.custom_rtc.SetValue(
|
||||||
|
std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
|
||||||
|
if (Core::System::GetInstance().IsPoweredOn()) {
|
||||||
|
const s64 posix_time{Settings::values.custom_rtc.GetValue()->count() +
|
||||||
|
Service::Time::TimeManager::GetExternalTimeZoneOffset()};
|
||||||
|
Core::System::GetInstance().GetTimeManager().UpdateLocalSystemClockTime(posix_time);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Settings::values.custom_rtc.SetValue(std::nullopt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -131,15 +148,6 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings::values.custom_rtc.UsingGlobal()) {
|
|
||||||
if (ui->custom_rtc_checkbox->isChecked()) {
|
|
||||||
Settings::values.custom_rtc.SetValue(
|
|
||||||
std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
|
|
||||||
} else {
|
|
||||||
Settings::values.custom_rtc.SetValue(std::nullopt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index,
|
||||||
ui->combo_language);
|
ui->combo_language);
|
||||||
|
|
Reference in New Issue