early-access version 3636

This commit is contained in:
pineappleEA
2023-06-04 09:49:04 +02:00
parent 667703d3e1
commit 19ca7d484f
14 changed files with 167 additions and 2025 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -22,6 +22,10 @@ s64 GetSecondsSinceEpoch() {
return std::chrono::duration_cast<std::chrono::seconds>(time_since_epoch).count() +
Settings::values.custom_rtc_differential;
}
s64 GetExternalRtcValue() {
return GetSecondsSinceEpoch() + TimeManager::GetExternalTimeZoneOffset();
}
} // Anonymous namespace
struct TimeManager::Impl final {
@@ -39,7 +43,7 @@ struct TimeManager::Impl final {
std::make_shared<Clock::EphemeralNetworkSystemClockContextWriter>()},
time_zone_content_manager{system} {
const auto system_time{Clock::TimeSpanType::FromSeconds(GetSecondsSinceEpoch())};
const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())};
SetupStandardSteadyClock(system, Common::UUID::MakeRandom(), system_time, {}, {});
SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds());
@@ -119,6 +123,14 @@ struct TimeManager::Impl final {
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) {
@@ -289,4 +301,13 @@ void TimeManager::SetupTimeZoneManager(std::string location_name,
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
if (Settings::GetTimeZoneString() == "auto") {
return Common::TimeZone::GetCurrentOffsetSeconds().count();
}
return 0;
}
} // namespace Service::Time

View File

@@ -64,6 +64,8 @@ public:
std::size_t total_location_name_count, u128 time_zone_rule_version,
FileSys::VirtualFile& vfs_file);
static s64 GetExternalTimeZoneOffset();
private:
Core::System& system;

View File

@@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <chrono>
#include <sstream>
#include "common/logging/log.h"
@@ -13,11 +12,7 @@
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/romfs.h"
#include "core/file_sys/system_archive/system_archive.h"
#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_types.h"
#include "core/hle/result.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/time/errors.h"
#include "core/hle/service/time/time_manager.h"
#include "core/hle/service/time/time_zone_content_manager.h"
@@ -76,14 +71,20 @@ TimeZoneContentManager::TimeZoneContentManager(Core::System& system_)
: system{system_}, location_name_cache{BuildLocationNameCache(system)} {}
void TimeZoneContentManager::Initialize(TimeManager& time_manager) {
std::string location_name;
const auto timezone_setting = Settings::GetTimeZoneString();
if (timezone_setting == "auto" || timezone_setting == "default") {
location_name = Common::TimeZone::GetDefaultTimeZone();
} else {
location_name = timezone_setting;
}
if (FileSys::VirtualFile vfs_file;
GetTimeZoneInfoFile(timezone_setting, vfs_file) == ResultSuccess) {
GetTimeZoneInfoFile(location_name, vfs_file) == ResultSuccess) {
const auto time_point{
time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system)};
time_manager.SetupTimeZoneManager(timezone_setting, time_point, location_name_cache.size(),
{}, vfs_file);
time_manager.SetupTimeZoneManager(location_name, time_point, location_name_cache.size(), {},
vfs_file);
} else {
time_zone_manager.MarkAsInitialized();
}
@@ -125,15 +126,8 @@ Result TimeZoneContentManager::GetTimeZoneInfoFile(const std::string& location_n
vfs_file = zoneinfo_dir->GetFileRelative(location_name);
if (!vfs_file) {
LOG_WARNING(Service_Time, "{:016X} has no file \"{}\"! Using system timezone.",
time_zone_binary_titleid, location_name);
const std::string system_time_zone{Common::TimeZone::FindSystemTimeZone()};
vfs_file = zoneinfo_dir->GetFile(system_time_zone);
}
if (!vfs_file) {
LOG_WARNING(Service_Time, "{:016X} has no file \"{}\"! Using default timezone.",
time_zone_binary_titleid, location_name);
LOG_ERROR(Service_Time, "{:016X} has no file \"{}\"! Using default timezone.",
time_zone_binary_titleid, location_name);
vfs_file = zoneinfo_dir->GetFile(Common::TimeZone::GetDefaultTimeZone());
}

View File

@@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <climits>
#include <limits>
#include "common/assert.h"
#include "common/logging/log.h"
@@ -10,7 +9,6 @@
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/registered_cache.h"
#include "core/hle/service/time/time_zone_manager.h"
#include "core/hle/service/time/time_zone_types.h"
namespace Service::Time::TimeZone {
@@ -144,9 +142,6 @@ static constexpr bool GetInteger(const char* name, int& offset, int& value, int
if (!IsDigit(temp)) {
return {};
}
if (temp == '0') {
return {};
}
do {
value = value * 10 + (temp - '0');
if (value > max) {
@@ -634,47 +629,11 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi
UNIMPLEMENTED();
}
}
const auto typesequiv = [](TimeZoneRule& rule, int a, int b) -> bool {
if (a < 0 || a >= rule.type_count || b < 0 || b >= rule.type_count) {
return {};
}
const struct TimeTypeInfo* ap = &rule.ttis[a];
const struct TimeTypeInfo* bp = &rule.ttis[b];
return (ap->gmt_offset == bp->gmt_offset && ap->is_dst == bp->is_dst &&
(std::strcmp(&rule.chars[ap->abbreviation_list_index],
&rule.chars[bp->abbreviation_list_index]) == 0));
};
if (time_zone_rule.type_count == 0) {
return {};
}
if (time_zone_rule.time_count > 1) {
if (time_zone_rule.ats[0] <= std::numeric_limits<s64>::max() - seconds_per_repeat) {
s64 repeatat = time_zone_rule.ats[0] + seconds_per_repeat;
int repeatattype = time_zone_rule.types[0];
for (int i = 1; i < time_zone_rule.time_count; ++i) {
if (time_zone_rule.ats[i] == repeatat &&
typesequiv(time_zone_rule, time_zone_rule.types[i], repeatattype)) {
time_zone_rule.go_back = true;
break;
}
}
}
if (std::numeric_limits<s64>::min() + seconds_per_repeat <=
time_zone_rule.ats[time_zone_rule.time_count - 1]) {
s64 repeatat = time_zone_rule.ats[time_zone_rule.time_count - 1] - seconds_per_repeat;
int repeatattype = time_zone_rule.types[time_zone_rule.time_count - 1];
for (int i = time_zone_rule.time_count; i >= 0; --i) {
if (time_zone_rule.ats[i] == repeatat &&
typesequiv(time_zone_rule, time_zone_rule.types[i], repeatattype)) {
time_zone_rule.go_ahead = true;
break;
}
}
}
UNIMPLEMENTED();
}
s32 default_type{};