aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpineappleEA <pineaea@gmail.com>2024-02-27 18:06:04 +0100
committerpineappleEA <pineaea@gmail.com>2024-02-27 18:06:04 +0100
commit90ca646c0d1bf63609dad5a22bc186a4ba5d9072 (patch)
treee98b23aa9ce1ccd44b48adbc409d30c94d4fa15f
parentf6fd2265b1bbcc8cd4dfe59e735dda1ceaafc6f9 (diff)
early-access version 4175EA-4175
-rwxr-xr-xREADME.md2
-rwxr-xr-xsrc/common/logging/backend.cpp2
-rwxr-xr-xsrc/common/logging/log.h4
-rwxr-xr-xsrc/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp4
-rwxr-xr-xsrc/core/file_sys/partition_filesystem.cpp8
-rwxr-xr-xsrc/core/file_sys/partition_filesystem.h1
-rwxr-xr-xsrc/core/file_sys/vfs/vfs_offset.cpp7
-rwxr-xr-xsrc/core/file_sys/vfs/vfs_offset.h3
-rwxr-xr-xsrc/core/file_sys/vfs/vfs_real.cpp14
-rwxr-xr-xsrc/core/file_sys/vfs/vfs_real.h3
-rwxr-xr-xsrc/core/hle/service/glue/time/manager.cpp37
-rwxr-xr-xsrc/core/hle/service/glue/time/manager.h4
-rwxr-xr-xsrc/core/hle/service/glue/time/static.cpp7
-rwxr-xr-xsrc/core/hle/service/glue/time/static.h1
-rwxr-xr-xsrc/core/hle/service/glue/time/time_zone.cpp27
-rwxr-xr-xsrc/core/hle/service/glue/time/time_zone.h7
-rwxr-xr-xsrc/core/hle/service/glue/time/time_zone_binary.cpp132
-rwxr-xr-xsrc/core/hle/service/glue/time/time_zone_binary.h43
-rwxr-xr-xsrc/core/hle/service/glue/time/worker.cpp55
-rwxr-xr-xsrc/core/hle/service/glue/time/worker.h8
-rwxr-xr-xsrc/core/hle/service/server_manager.cpp14
-rwxr-xr-xsrc/core/loader/loader.cpp17
-rwxr-xr-xsrc/video_core/renderer_opengl/renderer_opengl.cpp2
-rwxr-xr-xsrc/video_core/vulkan_common/vulkan_device.cpp8
24 files changed, 211 insertions, 199 deletions
diff --git a/README.md b/README.md
index 08db4df06..34c22597a 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
1yuzu emulator early access 1yuzu emulator early access
2============= 2=============
3 3
4This is the source code for early-access 4174. 4This is the source code for early-access 4175.
5 5
6## Legal Notice 6## Legal Notice
7 7
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 1168fbf6b..1041373bb 100755
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -343,7 +343,7 @@ void SetColorConsoleBackendEnabled(bool enabled) {
343} 343}
344 344
345void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, 345void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
346 unsigned int line_num, const char* function, const char* format, 346 unsigned int line_num, const char* function, fmt::string_view format,
347 const fmt::format_args& args) { 347 const fmt::format_args& args) {
348 if (!initialization_in_progress_suppress_logging) { 348 if (!initialization_in_progress_suppress_logging) {
349 Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function, 349 Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function,
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index ba521a258..cd5d31a3f 100755
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -24,12 +24,12 @@ constexpr const char* TrimSourcePath(std::string_view source) {
24 24
25/// Logs a message to the global logger, using fmt 25/// Logs a message to the global logger, using fmt
26void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, 26void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
27 unsigned int line_num, const char* function, const char* format, 27 unsigned int line_num, const char* function, fmt::string_view format,
28 const fmt::format_args& args); 28 const fmt::format_args& args);
29 29
30template <typename... Args> 30template <typename... Args>
31void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num, 31void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
32 const char* function, const char* format, const Args&... args) { 32 const char* function, fmt::format_string<Args...> format, const Args&... args) {
33 FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format, 33 FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format,
34 fmt::make_format_args(args...)); 34 fmt::make_format_args(args...));
35} 35}
diff --git a/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp b/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp
index 022424229..efc5aa0b1 100755
--- a/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp
+++ b/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp
@@ -31,8 +31,8 @@ AesXtsStorage::AesXtsStorage(VirtualFile base, const void* key1, const void* key
31 ASSERT(iv_size == IvSize); 31 ASSERT(iv_size == IvSize);
32 ASSERT(Common::IsAligned(m_block_size, AesBlockSize)); 32 ASSERT(Common::IsAligned(m_block_size, AesBlockSize));
33 33
34 std::memcpy(m_key.data() + 0, key1, KeySize); 34 std::memcpy(m_key.data() + 0, key1, KeySize / 2);
35 std::memcpy(m_key.data() + 0x10, key2, KeySize); 35 std::memcpy(m_key.data() + 0x10, key2, KeySize / 2);
36 std::memcpy(m_iv.data(), iv, IvSize); 36 std::memcpy(m_iv.data(), iv, IvSize);
37 37
38 m_cipher.emplace(m_key, Core::Crypto::Mode::XTS); 38 m_cipher.emplace(m_key, Core::Crypto::Mode::XTS);
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp
index 2d8b910dd..4ffbd5788 100755
--- a/src/core/file_sys/partition_filesystem.cpp
+++ b/src/core/file_sys/partition_filesystem.cpp
@@ -105,12 +105,4 @@ VirtualDir PartitionFilesystem::GetParentDirectory() const {
105 return nullptr; 105 return nullptr;
106} 106}
107 107
108void PartitionFilesystem::PrintDebugInfo() const {
109 LOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic);
110 LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries);
111 for (u32 i = 0; i < pfs_header.num_entries; i++) {
112 LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes)", i,
113 pfs_files[i]->GetName(), pfs_files[i]->GetSize());
114 }
115}
116} // namespace FileSys 108} // namespace FileSys
diff --git a/src/core/file_sys/partition_filesystem.h b/src/core/file_sys/partition_filesystem.h
index d529b8d59..c28aea93b 100755
--- a/src/core/file_sys/partition_filesystem.h
+++ b/src/core/file_sys/partition_filesystem.h
@@ -35,7 +35,6 @@ public:
35 std::vector<VirtualDir> GetSubdirectories() const override; 35 std::vector<VirtualDir> GetSubdirectories() const override;
36 std::string GetName() const override; 36 std::string GetName() const override;
37 VirtualDir GetParentDirectory() const override; 37 VirtualDir GetParentDirectory() const override;
38 void PrintDebugInfo() const;
39 38
40private: 39private:
41 struct Header { 40 struct Header {
diff --git a/src/core/file_sys/vfs/vfs_offset.cpp b/src/core/file_sys/vfs/vfs_offset.cpp
index 1a37d2670..6b51ed3eb 100755
--- a/src/core/file_sys/vfs/vfs_offset.cpp
+++ b/src/core/file_sys/vfs/vfs_offset.cpp
@@ -9,9 +9,8 @@
9namespace FileSys { 9namespace FileSys {
10 10
11OffsetVfsFile::OffsetVfsFile(VirtualFile file_, std::size_t size_, std::size_t offset_, 11OffsetVfsFile::OffsetVfsFile(VirtualFile file_, std::size_t size_, std::size_t offset_,
12 std::string name_, VirtualDir parent_) 12 std::string name_)
13 : file(file_), offset(offset_), size(size_), name(std::move(name_)), 13 : file(file_), offset(offset_), size(size_), name(std::move(name_)) {}
14 parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
15 14
16OffsetVfsFile::~OffsetVfsFile() = default; 15OffsetVfsFile::~OffsetVfsFile() = default;
17 16
@@ -37,7 +36,7 @@ bool OffsetVfsFile::Resize(std::size_t new_size) {
37} 36}
38 37
39VirtualDir OffsetVfsFile::GetContainingDirectory() const { 38VirtualDir OffsetVfsFile::GetContainingDirectory() const {
40 return parent; 39 return nullptr;
41} 40}
42 41
43bool OffsetVfsFile::IsWritable() const { 42bool OffsetVfsFile::IsWritable() const {
diff --git a/src/core/file_sys/vfs/vfs_offset.h b/src/core/file_sys/vfs/vfs_offset.h
index 4abe41d8e..9800b4fd0 100755
--- a/src/core/file_sys/vfs/vfs_offset.h
+++ b/src/core/file_sys/vfs/vfs_offset.h
@@ -16,7 +16,7 @@ namespace FileSys {
16class OffsetVfsFile : public VfsFile { 16class OffsetVfsFile : public VfsFile {
17public: 17public:
18 OffsetVfsFile(VirtualFile file, std::size_t size, std::size_t offset = 0, 18 OffsetVfsFile(VirtualFile file, std::size_t size, std::size_t offset = 0,
19 std::string new_name = "", VirtualDir new_parent = nullptr); 19 std::string new_name = "");
20 ~OffsetVfsFile() override; 20 ~OffsetVfsFile() override;
21 21
22 std::string GetName() const override; 22 std::string GetName() const override;
@@ -44,7 +44,6 @@ private:
44 std::size_t offset; 44 std::size_t offset;
45 std::size_t size; 45 std::size_t size;
46 std::string name; 46 std::string name;
47 VirtualDir parent;
48}; 47};
49 48
50} // namespace FileSys 49} // namespace FileSys
diff --git a/src/core/file_sys/vfs/vfs_real.cpp b/src/core/file_sys/vfs/vfs_real.cpp
index 3ad073e4a..052684e9d 100755
--- a/src/core/file_sys/vfs/vfs_real.cpp
+++ b/src/core/file_sys/vfs/vfs_real.cpp
@@ -76,6 +76,7 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const {
76} 76}
77 77
78VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::optional<u64> size, 78VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::optional<u64> size,
79 std::optional<std::string> parent_path,
79 OpenMode perms) { 80 OpenMode perms) {
80 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); 81 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
81 std::scoped_lock lk{list_lock}; 82 std::scoped_lock lk{list_lock};
@@ -94,14 +95,14 @@ VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::op
94 this->InsertReferenceIntoListLocked(*reference); 95 this->InsertReferenceIntoListLocked(*reference);
95 96
96 auto file = std::shared_ptr<RealVfsFile>( 97 auto file = std::shared_ptr<RealVfsFile>(
97 new RealVfsFile(*this, std::move(reference), path, perms, size)); 98 new RealVfsFile(*this, std::move(reference), path, perms, size, std::move(parent_path)));
98 cache[path] = file; 99 cache[path] = file;
99 100
100 return file; 101 return file;
101} 102}
102 103
103VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, OpenMode perms) { 104VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, OpenMode perms) {
104 return OpenFileFromEntry(path_, {}, perms); 105 return OpenFileFromEntry(path_, {}, {}, perms);
105} 106}
106 107
107VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, OpenMode perms) { 108VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, OpenMode perms) {
@@ -268,10 +269,11 @@ void RealVfsFilesystem::RemoveReferenceFromListLocked(FileReference& reference)
268} 269}
269 270
270RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_, 271RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_,
271 const std::string& path_, OpenMode perms_, std::optional<u64> size_) 272 const std::string& path_, OpenMode perms_, std::optional<u64> size_,
273 std::optional<std::string> parent_path_)
272 : base(base_), reference(std::move(reference_)), path(path_), 274 : base(base_), reference(std::move(reference_)), path(path_),
273 parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponentsCopy(path_)), 275 parent_path(parent_path_ ? std::move(*parent_path_) : FS::GetParentPath(path_)),
274 size(size_), perms(perms_) {} 276 path_components(FS::SplitPathComponentsCopy(path_)), size(size_), perms(perms_) {}
275 277
276RealVfsFile::~RealVfsFile() { 278RealVfsFile::~RealVfsFile() {
277 base.DropReference(std::move(reference)); 279 base.DropReference(std::move(reference));
@@ -348,7 +350,7 @@ std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>(
348 &out](const std::filesystem::directory_entry& entry) { 350 &out](const std::filesystem::directory_entry& entry) {
349 const auto full_path_string = FS::PathToUTF8String(entry.path()); 351 const auto full_path_string = FS::PathToUTF8String(entry.path());
350 352
351 out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), perms)); 353 out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), path, perms));
352 354
353 return true; 355 return true;
354 }; 356 };
diff --git a/src/core/file_sys/vfs/vfs_real.h b/src/core/file_sys/vfs/vfs_real.h
index 5c2172cce..a773fc375 100755
--- a/src/core/file_sys/vfs/vfs_real.h
+++ b/src/core/file_sys/vfs/vfs_real.h
@@ -62,6 +62,7 @@ private:
62private: 62private:
63 friend class RealVfsDirectory; 63 friend class RealVfsDirectory;
64 VirtualFile OpenFileFromEntry(std::string_view path, std::optional<u64> size, 64 VirtualFile OpenFileFromEntry(std::string_view path, std::optional<u64> size,
65 std::optional<std::string> parent_path,
65 OpenMode perms = OpenMode::Read); 66 OpenMode perms = OpenMode::Read);
66 67
67private: 68private:
@@ -91,7 +92,7 @@ public:
91private: 92private:
92 RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference, 93 RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
93 const std::string& path, OpenMode perms = OpenMode::Read, 94 const std::string& path, OpenMode perms = OpenMode::Read,
94 std::optional<u64> size = {}); 95 std::optional<u64> size = {}, std::optional<std::string> parent_path = {});
95 96
96 RealVfsFilesystem& base; 97 RealVfsFilesystem& base;
97 std::unique_ptr<FileReference> reference; 98 std::unique_ptr<FileReference> reference;
diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp
index cb88486dd..77bf8896c 100755
--- a/src/core/hle/service/glue/time/manager.cpp
+++ b/src/core/hle/service/glue/time/manager.cpp
@@ -11,7 +11,6 @@
11#include "core/file_sys/vfs/vfs.h" 11#include "core/file_sys/vfs/vfs.h"
12#include "core/hle/kernel/svc.h" 12#include "core/hle/kernel/svc.h"
13#include "core/hle/service/glue/time/manager.h" 13#include "core/hle/service/glue/time/manager.h"
14#include "core/hle/service/glue/time/time_zone_binary.h"
15#include "core/hle/service/psc/time/service_manager.h" 14#include "core/hle/service/psc/time/service_manager.h"
16#include "core/hle/service/psc/time/static.h" 15#include "core/hle/service/psc/time/static.h"
17#include "core/hle/service/psc/time/system_clock.h" 16#include "core/hle/service/psc/time/system_clock.h"
@@ -20,8 +19,8 @@
20#include "core/hle/service/sm/sm.h" 19#include "core/hle/service/sm/sm.h"
21 20
22namespace Service::Glue::Time { 21namespace Service::Glue::Time {
23namespace { 22
24s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) { 23static s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
25 constexpr auto is_leap = [](s32 year) -> bool { 24 constexpr auto is_leap = [](s32 year) -> bool {
26 return (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0)); 25 return (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0));
27 }; 26 };
@@ -50,7 +49,8 @@ s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
50 return epoch_s - 62135683200ll; 49 return epoch_s - 62135683200ll;
51} 50}
52 51
53s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) { 52static s64 GetEpochTimeFromInitialYear(
53 std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) {
54 s32 year{2000}; 54 s32 year{2000};
55 set_sys->GetSettingsItemValueImpl(year, "time", "standard_user_clock_initial_year"); 55 set_sys->GetSettingsItemValueImpl(year, "time", "standard_user_clock_initial_year");
56 56
@@ -65,31 +65,32 @@ s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsSer
65 return CalendarTimeToEpoch(calendar); 65 return CalendarTimeToEpoch(calendar);
66} 66}
67 67
68Service::PSC::Time::LocationName GetTimeZoneString(Service::PSC::Time::LocationName& in_name) { 68static Service::PSC::Time::LocationName GetTimeZoneString(
69 TimeZoneBinary& time_zone_binary, Service::PSC::Time::LocationName& in_name) {
69 auto configured_zone = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue()); 70 auto configured_zone = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue());
70 71
71 Service::PSC::Time::LocationName configured_name{}; 72 Service::PSC::Time::LocationName configured_name{};
72 std::memcpy(configured_name.data(), configured_zone.data(), 73 std::memcpy(configured_name.data(), configured_zone.data(),
73 std::min(configured_name.size(), configured_zone.size())); 74 std::min(configured_name.size(), configured_zone.size()));
74 75
75 if (!IsTimeZoneBinaryValid(configured_name)) { 76 if (!time_zone_binary.IsValid(configured_name)) {
76 configured_zone = Common::TimeZone::FindSystemTimeZone(); 77 configured_zone = Common::TimeZone::FindSystemTimeZone();
77 configured_name = {}; 78 configured_name = {};
78 std::memcpy(configured_name.data(), configured_zone.data(), 79 std::memcpy(configured_name.data(), configured_zone.data(),
79 std::min(configured_name.size(), configured_zone.size())); 80 std::min(configured_name.size(), configured_zone.size()));
80 } 81 }
81 82
82 ASSERT_MSG(IsTimeZoneBinaryValid(configured_name), "Invalid time zone {}!", 83 ASSERT_MSG(time_zone_binary.IsValid(configured_name), "Invalid time zone {}!",
83 configured_name.data()); 84 configured_name.data());
84 85
85 return configured_name; 86 return configured_name;
86} 87}
87 88
88} // namespace
89
90TimeManager::TimeManager(Core::System& system) 89TimeManager::TimeManager(Core::System& system)
91 : m_steady_clock_resource{system}, m_worker{system, m_steady_clock_resource, 90 : m_steady_clock_resource{system}, m_time_zone_binary{system}, m_worker{
92 m_file_timestamp_worker} { 91 system,
92 m_steady_clock_resource,
93 m_file_timestamp_worker} {
93 m_time_m = 94 m_time_m =
94 system.ServiceManager().GetService<Service::PSC::Time::ServiceManager>("time:m", true); 95 system.ServiceManager().GetService<Service::PSC::Time::ServiceManager>("time:m", true);
95 96
@@ -99,7 +100,7 @@ TimeManager::TimeManager(Core::System& system)
99 m_set_sys = 100 m_set_sys =
100 system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); 101 system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
101 102
102 res = MountTimeZoneBinary(system); 103 res = m_time_zone_binary.Mount();
103 ASSERT(res == ResultSuccess); 104 ASSERT(res == ResultSuccess);
104 105
105 m_worker.Initialize(m_time_sm, m_set_sys); 106 m_worker.Initialize(m_time_sm, m_set_sys);
@@ -187,10 +188,6 @@ TimeManager::TimeManager(Core::System& system)
187 } 188 }
188} 189}
189 190
190TimeManager::~TimeManager() {
191 ResetTimeZoneBinary();
192}
193
194Result TimeManager::SetupStandardSteadyClockCore() { 191Result TimeManager::SetupStandardSteadyClockCore() {
195 Common::UUID external_clock_source_id{}; 192 Common::UUID external_clock_source_id{};
196 auto res = m_set_sys->GetExternalSteadyClockSourceId(&external_clock_source_id); 193 auto res = m_set_sys->GetExternalSteadyClockSourceId(&external_clock_source_id);
@@ -236,7 +233,7 @@ Result TimeManager::SetupTimeZoneServiceCore() {
236 auto res = m_set_sys->GetDeviceTimeZoneLocationName(&name); 233 auto res = m_set_sys->GetDeviceTimeZoneLocationName(&name);
237 ASSERT(res == ResultSuccess); 234 ASSERT(res == ResultSuccess);
238 235
239 auto configured_zone = GetTimeZoneString(name); 236 auto configured_zone = GetTimeZoneString(m_time_zone_binary, name);
240 237
241 if (configured_zone != name) { 238 if (configured_zone != name) {
242 m_set_sys->SetDeviceTimeZoneLocationName(configured_zone); 239 m_set_sys->SetDeviceTimeZoneLocationName(configured_zone);
@@ -254,13 +251,13 @@ Result TimeManager::SetupTimeZoneServiceCore() {
254 res = m_set_sys->GetDeviceTimeZoneLocationUpdatedTime(&time_point); 251 res = m_set_sys->GetDeviceTimeZoneLocationUpdatedTime(&time_point);
255 ASSERT(res == ResultSuccess); 252 ASSERT(res == ResultSuccess);
256 253
257 auto location_count = GetTimeZoneCount(); 254 auto location_count = m_time_zone_binary.GetTimeZoneCount();
258 Service::PSC::Time::RuleVersion rule_version{}; 255 Service::PSC::Time::RuleVersion rule_version{};
259 GetTimeZoneVersion(rule_version); 256 m_time_zone_binary.GetTimeZoneVersion(rule_version);
260 257
261 std::span<const u8> rule_buffer{}; 258 std::span<const u8> rule_buffer{};
262 size_t rule_size{}; 259 size_t rule_size{};
263 res = GetTimeZoneRule(rule_buffer, rule_size, name); 260 res = m_time_zone_binary.GetTimeZoneRule(rule_buffer, rule_size, name);
264 ASSERT(res == ResultSuccess); 261 ASSERT(res == ResultSuccess);
265 262
266 res = m_time_m->SetupTimeZoneServiceCore(name, rule_version, location_count, time_point, 263 res = m_time_m->SetupTimeZoneServiceCore(name, rule_version, location_count, time_point,
diff --git a/src/core/hle/service/glue/time/manager.h b/src/core/hle/service/glue/time/manager.h
index bb4b65049..87e6a21fd 100755
--- a/src/core/hle/service/glue/time/manager.h
+++ b/src/core/hle/service/glue/time/manager.h
@@ -10,6 +10,7 @@
10#include "core/file_sys/vfs/vfs_types.h" 10#include "core/file_sys/vfs/vfs_types.h"
11#include "core/hle/service/glue/time/file_timestamp_worker.h" 11#include "core/hle/service/glue/time/file_timestamp_worker.h"
12#include "core/hle/service/glue/time/standard_steady_clock_resource.h" 12#include "core/hle/service/glue/time/standard_steady_clock_resource.h"
13#include "core/hle/service/glue/time/time_zone_binary.h"
13#include "core/hle/service/glue/time/worker.h" 14#include "core/hle/service/glue/time/worker.h"
14#include "core/hle/service/service.h" 15#include "core/hle/service/service.h"
15 16
@@ -26,7 +27,7 @@ namespace Service::Glue::Time {
26class TimeManager { 27class TimeManager {
27public: 28public:
28 explicit TimeManager(Core::System& system); 29 explicit TimeManager(Core::System& system);
29 ~TimeManager(); 30 ~TimeManager() = default;
30 31
31 std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; 32 std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
32 33
@@ -34,6 +35,7 @@ public:
34 std::shared_ptr<Service::PSC::Time::StaticService> m_time_sm{}; 35 std::shared_ptr<Service::PSC::Time::StaticService> m_time_sm{};
35 StandardSteadyClockResource m_steady_clock_resource; 36 StandardSteadyClockResource m_steady_clock_resource;
36 FileTimestampWorker m_file_timestamp_worker; 37 FileTimestampWorker m_file_timestamp_worker;
38 TimeZoneBinary m_time_zone_binary;
37 TimeWorker m_worker; 39 TimeWorker m_worker;
38 40
39private: 41private:
diff --git a/src/core/hle/service/glue/time/static.cpp b/src/core/hle/service/glue/time/static.cpp
index b801faef2..d8672b724 100755
--- a/src/core/hle/service/glue/time/static.cpp
+++ b/src/core/hle/service/glue/time/static.cpp
@@ -26,8 +26,9 @@ StaticService::StaticService(Core::System& system_,
26 std::shared_ptr<TimeManager> time, const char* name) 26 std::shared_ptr<TimeManager> time, const char* name)
27 : ServiceFramework{system_, name}, m_system{system_}, m_time_m{time->m_time_m}, 27 : ServiceFramework{system_, name}, m_system{system_}, m_time_m{time->m_time_m},
28 m_setup_info{setup_info}, m_time_sm{time->m_time_sm}, 28 m_setup_info{setup_info}, m_time_sm{time->m_time_sm},
29 m_file_timestamp_worker{time->m_file_timestamp_worker}, m_standard_steady_clock_resource{ 29 m_file_timestamp_worker{time->m_file_timestamp_worker},
30 time->m_steady_clock_resource} { 30 m_standard_steady_clock_resource{time->m_steady_clock_resource},
31 m_time_zone_binary{time->m_time_zone_binary} {
31 // clang-format off 32 // clang-format off
32 static const FunctionInfo functions[] = { 33 static const FunctionInfo functions[] = {
33 {0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"}, 34 {0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"},
@@ -106,7 +107,7 @@ Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_servi
106 107
107 *out_service = std::make_shared<TimeZoneService>( 108 *out_service = std::make_shared<TimeZoneService>(
108 m_system, m_file_timestamp_worker, m_setup_info.can_write_timezone_device_location, 109 m_system, m_file_timestamp_worker, m_setup_info.can_write_timezone_device_location,
109 m_time_zone); 110 m_time_zone_binary, m_time_zone);
110 R_SUCCEED(); 111 R_SUCCEED();
111} 112}
112 113
diff --git a/src/core/hle/service/glue/time/static.h b/src/core/hle/service/glue/time/static.h
index 5d3623182..7bb0e0b36 100755
--- a/src/core/hle/service/glue/time/static.h
+++ b/src/core/hle/service/glue/time/static.h
@@ -80,5 +80,6 @@ private:
80 std::shared_ptr<Service::PSC::Time::TimeZoneService> m_time_zone; 80 std::shared_ptr<Service::PSC::Time::TimeZoneService> m_time_zone;
81 FileTimestampWorker& m_file_timestamp_worker; 81 FileTimestampWorker& m_file_timestamp_worker;
82 StandardSteadyClockResource& m_standard_steady_clock_resource; 82 StandardSteadyClockResource& m_standard_steady_clock_resource;
83 TimeZoneBinary& m_time_zone_binary;
83}; 84};
84} // namespace Service::Glue::Time 85} // namespace Service::Glue::Time
diff --git a/src/core/hle/service/glue/time/time_zone.cpp b/src/core/hle/service/glue/time/time_zone.cpp
index f4d0c87d5..b2e815965 100755
--- a/src/core/hle/service/glue/time/time_zone.cpp
+++ b/src/core/hle/service/glue/time/time_zone.cpp
@@ -15,19 +15,16 @@
15#include "core/hle/service/sm/sm.h" 15#include "core/hle/service/sm/sm.h"
16 16
17namespace Service::Glue::Time { 17namespace Service::Glue::Time {
18namespace {
19static std::mutex g_list_mutex;
20static Common::IntrusiveListBaseTraits<Service::PSC::Time::OperationEvent>::ListType g_list_nodes{};
21} // namespace
22 18
23TimeZoneService::TimeZoneService( 19TimeZoneService::TimeZoneService(
24 Core::System& system_, FileTimestampWorker& file_timestamp_worker, 20 Core::System& system_, FileTimestampWorker& file_timestamp_worker,
25 bool can_write_timezone_device_location, 21 bool can_write_timezone_device_location, TimeZoneBinary& time_zone_binary,
26 std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service) 22 std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service)
27 : ServiceFramework{system_, "ITimeZoneService"}, m_system{system}, 23 : ServiceFramework{system_, "ITimeZoneService"}, m_system{system},
28 m_can_write_timezone_device_location{can_write_timezone_device_location}, 24 m_can_write_timezone_device_location{can_write_timezone_device_location},
29 m_file_timestamp_worker{file_timestamp_worker}, 25 m_file_timestamp_worker{file_timestamp_worker}, m_wrapped_service{std::move(
30 m_wrapped_service{std::move(time_zone_service)}, m_operation_event{m_system} { 26 time_zone_service)},
27 m_operation_event{m_system}, m_time_zone_binary{time_zone_binary} {
31 // clang-format off 28 // clang-format off
32 static const FunctionInfo functions[] = { 29 static const FunctionInfo functions[] = {
33 {0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"}, 30 {0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"},
@@ -48,7 +45,6 @@ TimeZoneService::TimeZoneService(
48 // clang-format on 45 // clang-format on
49 RegisterHandlers(functions); 46 RegisterHandlers(functions);
50 47
51 g_list_nodes.clear();
52 m_set_sys = 48 m_set_sys =
53 m_system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); 49 m_system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
54} 50}
@@ -69,13 +65,13 @@ Result TimeZoneService::SetDeviceLocationName(
69 LOG_DEBUG(Service_Time, "called. location_name={}", location_name); 65 LOG_DEBUG(Service_Time, "called. location_name={}", location_name);
70 66
71 R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied); 67 R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied);
72 R_UNLESS(IsTimeZoneBinaryValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound); 68 R_UNLESS(m_time_zone_binary.IsValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound);
73 69
74 std::scoped_lock l{m_mutex}; 70 std::scoped_lock l{m_mutex};
75 71
76 std::span<const u8> binary{}; 72 std::span<const u8> binary{};
77 size_t binary_size{}; 73 size_t binary_size{};
78 R_TRY(GetTimeZoneRule(binary, binary_size, location_name)) 74 R_TRY(m_time_zone_binary.GetTimeZoneRule(binary, binary_size, location_name))
79 75
80 R_TRY(m_wrapped_service->SetDeviceLocationNameWithTimeZoneRule(location_name, binary)); 76 R_TRY(m_wrapped_service->SetDeviceLocationNameWithTimeZoneRule(location_name, binary));
81 77
@@ -88,8 +84,8 @@ Result TimeZoneService::SetDeviceLocationName(
88 m_set_sys->SetDeviceTimeZoneLocationName(name); 84 m_set_sys->SetDeviceTimeZoneLocationName(name);
89 m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(time_point); 85 m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(time_point);
90 86
91 std::scoped_lock m{g_list_mutex}; 87 std::scoped_lock m{m_list_mutex};
92 for (auto& operation_event : g_list_nodes) { 88 for (auto& operation_event : m_list_nodes) {
93 operation_event.m_event->Signal(); 89 operation_event.m_event->Signal();
94 } 90 }
95 R_SUCCEED(); 91 R_SUCCEED();
@@ -112,7 +108,8 @@ Result TimeZoneService::LoadLocationNameList(
112 }; 108 };
113 109
114 std::scoped_lock l{m_mutex}; 110 std::scoped_lock l{m_mutex};
115 R_RETURN(GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index)); 111 R_RETURN(
112 m_time_zone_binary.GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index));
116} 113}
117 114
118Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule, 115Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule,
@@ -122,7 +119,7 @@ Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule,
122 std::scoped_lock l{m_mutex}; 119 std::scoped_lock l{m_mutex};
123 std::span<const u8> binary{}; 120 std::span<const u8> binary{};
124 size_t binary_size{}; 121 size_t binary_size{};
125 R_TRY(GetTimeZoneRule(binary, binary_size, name)) 122 R_TRY(m_time_zone_binary.GetTimeZoneRule(binary, binary_size, name))
126 R_RETURN(m_wrapped_service->ParseTimeZoneBinary(out_rule, binary)); 123 R_RETURN(m_wrapped_service->ParseTimeZoneBinary(out_rule, binary));
127} 124}
128 125
@@ -174,7 +171,7 @@ Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle(
174 m_operation_event.m_ctx.CreateEvent("Psc:TimeZoneService:OperationEvent"); 171 m_operation_event.m_ctx.CreateEvent("Psc:TimeZoneService:OperationEvent");
175 operation_event_initialized = true; 172 operation_event_initialized = true;
176 std::scoped_lock l{m_mutex}; 173 std::scoped_lock l{m_mutex};
177 g_list_nodes.push_back(m_operation_event); 174 m_list_nodes.push_back(m_operation_event);
178 } 175 }
179 176
180 *out_event = &m_operation_event.m_event->GetReadableEvent(); 177 *out_event = &m_operation_event.m_event->GetReadableEvent();
diff --git a/src/core/hle/service/glue/time/time_zone.h b/src/core/hle/service/glue/time/time_zone.h
index beb54ddde..2b130b275 100755
--- a/src/core/hle/service/glue/time/time_zone.h
+++ b/src/core/hle/service/glue/time/time_zone.h
@@ -32,6 +32,7 @@ class TimeZoneService;
32 32
33namespace Service::Glue::Time { 33namespace Service::Glue::Time {
34class FileTimestampWorker; 34class FileTimestampWorker;
35class TimeZoneBinary;
35 36
36class TimeZoneService final : public ServiceFramework<TimeZoneService> { 37class TimeZoneService final : public ServiceFramework<TimeZoneService> {
37 using InRule = InLargeData<Tz::Rule, BufferAttr_HipcMapAlias>; 38 using InRule = InLargeData<Tz::Rule, BufferAttr_HipcMapAlias>;
@@ -40,7 +41,7 @@ class TimeZoneService final : public ServiceFramework<TimeZoneService> {
40public: 41public:
41 explicit TimeZoneService( 42 explicit TimeZoneService(
42 Core::System& system, FileTimestampWorker& file_timestamp_worker, 43 Core::System& system, FileTimestampWorker& file_timestamp_worker,
43 bool can_write_timezone_device_location, 44 bool can_write_timezone_device_location, TimeZoneBinary& time_zone_binary,
44 std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service); 45 std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service);
45 46
46 ~TimeZoneService() override; 47 ~TimeZoneService() override;
@@ -85,6 +86,10 @@ private:
85 std::mutex m_mutex; 86 std::mutex m_mutex;
86 bool operation_event_initialized{}; 87 bool operation_event_initialized{};
87 Service::PSC::Time::OperationEvent m_operation_event; 88 Service::PSC::Time::OperationEvent m_operation_event;
89 TimeZoneBinary& m_time_zone_binary;
90
91 std::mutex m_list_mutex;
92 Common::IntrusiveListBaseTraits<Service::PSC::Time::OperationEvent>::ListType m_list_nodes{};
88}; 93};
89 94
90} // namespace Service::Glue::Time 95} // namespace Service::Glue::Time
diff --git a/src/core/hle/service/glue/time/time_zone_binary.cpp b/src/core/hle/service/glue/time/time_zone_binary.cpp
index 18c6abd6b..3cc1a62af 100755
--- a/src/core/hle/service/glue/time/time_zone_binary.cpp
+++ b/src/core/hle/service/glue/time/time_zone_binary.cpp
@@ -12,41 +12,17 @@
12#include "core/hle/service/glue/time/time_zone_binary.h" 12#include "core/hle/service/glue/time/time_zone_binary.h"
13 13
14namespace Service::Glue::Time { 14namespace Service::Glue::Time {
15namespace {
16constexpr u64 TimeZoneBinaryId = 0x10000000000080E; 15constexpr u64 TimeZoneBinaryId = 0x10000000000080E;
17 16
18static FileSys::VirtualDir g_time_zone_binary_romfs{}; 17void TimeZoneBinary::Reset() {
19static Result g_time_zone_binary_mount_result{ResultUnknown}; 18 time_zone_binary_romfs = {};
20static std::vector<u8> g_time_zone_scratch_space(0x2800, 0); 19 time_zone_binary_mount_result = ResultUnknown;
21 20 time_zone_scratch_space.clear();
22Result TimeZoneReadBinary(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size, 21 time_zone_scratch_space.resize(0x2800, 0);
23 std::string_view path) {
24 R_UNLESS(g_time_zone_binary_mount_result == ResultSuccess, g_time_zone_binary_mount_result);
25
26 auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)};
27 R_UNLESS(vfs_file, ResultUnknown);
28
29 auto file_size{vfs_file->GetSize()};
30 R_UNLESS(file_size > 0, ResultUnknown);
31
32 R_UNLESS(file_size <= out_buffer_size, Service::PSC::Time::ResultFailed);
33
34 out_read_size = vfs_file->Read(out_buffer.data(), file_size);
35 R_UNLESS(out_read_size > 0, ResultUnknown);
36
37 R_SUCCEED();
38}
39} // namespace
40
41void ResetTimeZoneBinary() {
42 g_time_zone_binary_romfs = {};
43 g_time_zone_binary_mount_result = ResultUnknown;
44 g_time_zone_scratch_space.clear();
45 g_time_zone_scratch_space.resize(0x2800, 0);
46} 22}
47 23
48Result MountTimeZoneBinary(Core::System& system) { 24Result TimeZoneBinary::Mount() {
49 ResetTimeZoneBinary(); 25 Reset();
50 26
51 auto& fsc{system.GetFileSystemController()}; 27 auto& fsc{system.GetFileSystemController()};
52 std::unique_ptr<FileSys::NCA> nca{}; 28 std::unique_ptr<FileSys::NCA> nca{};
@@ -58,60 +34,79 @@ Result MountTimeZoneBinary(Core::System& system) {
58 nca = bis_system->GetEntry(TimeZoneBinaryId, FileSys::ContentRecordType::Data); 34 nca = bis_system->GetEntry(TimeZoneBinaryId, FileSys::ContentRecordType::Data);
59 35
60 if (nca) { 36 if (nca) {
61 g_time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS()); 37 time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS());
62 } 38 }
63 39
64 if (g_time_zone_binary_romfs) { 40 if (time_zone_binary_romfs) {
65 // Validate that the romfs is readable, using invalid firmware keys can cause this to get 41 // Validate that the romfs is readable, using invalid firmware keys can cause this to get
66 // set but the files to be garbage. In that case, we want to hit the next path and 42 // set but the files to be garbage. In that case, we want to hit the next path and
67 // synthesise them instead. 43 // synthesise them instead.
68 g_time_zone_binary_mount_result = ResultSuccess; 44 time_zone_binary_mount_result = ResultSuccess;
69 Service::PSC::Time::LocationName name{"Etc/GMT"}; 45 Service::PSC::Time::LocationName name{"Etc/GMT"};
70 if (!IsTimeZoneBinaryValid(name)) { 46 if (!IsValid(name)) {
71 ResetTimeZoneBinary(); 47 Reset();
72 } 48 }
73 } 49 }
74 50
75 if (!g_time_zone_binary_romfs) { 51 if (!time_zone_binary_romfs) {
76 g_time_zone_binary_romfs = FileSys::ExtractRomFS( 52 time_zone_binary_romfs = FileSys::ExtractRomFS(
77 FileSys::SystemArchive::SynthesizeSystemArchive(TimeZoneBinaryId)); 53 FileSys::SystemArchive::SynthesizeSystemArchive(TimeZoneBinaryId));
78 } 54 }
79 55
80 R_UNLESS(g_time_zone_binary_romfs, ResultUnknown); 56 R_UNLESS(time_zone_binary_romfs, ResultUnknown);
57
58 time_zone_binary_mount_result = ResultSuccess;
59 R_SUCCEED();
60}
61
62Result TimeZoneBinary::Read(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
63 std::string_view path) {
64 R_UNLESS(time_zone_binary_mount_result == ResultSuccess, time_zone_binary_mount_result);
65
66 auto vfs_file{time_zone_binary_romfs->GetFileRelative(path)};
67 R_UNLESS(vfs_file, ResultUnknown);
68
69 auto file_size{vfs_file->GetSize()};
70 R_UNLESS(file_size > 0, ResultUnknown);
71
72 R_UNLESS(file_size <= out_buffer_size, Service::PSC::Time::ResultFailed);
73
74 out_read_size = vfs_file->Read(out_buffer.data(), file_size);
75 R_UNLESS(out_read_size > 0, ResultUnknown);
81 76
82 g_time_zone_binary_mount_result = ResultSuccess;
83 R_SUCCEED(); 77 R_SUCCEED();
84} 78}
85 79
86void GetTimeZoneBinaryListPath(std::string& out_path) { 80void TimeZoneBinary::GetListPath(std::string& out_path) {
87 if (g_time_zone_binary_mount_result != ResultSuccess) { 81 if (time_zone_binary_mount_result != ResultSuccess) {
88 return; 82 return;
89 } 83 }
90 // out_path = fmt::format("{}:/binaryList.txt", "TimeZoneBinary"); 84 // out_path = fmt::format("{}:/binaryList.txt", "TimeZoneBinary");
91 out_path = "/binaryList.txt"; 85 out_path = "/binaryList.txt";
92} 86}
93 87
94void GetTimeZoneBinaryVersionPath(std::string& out_path) { 88void TimeZoneBinary::GetVersionPath(std::string& out_path) {
95 if (g_time_zone_binary_mount_result != ResultSuccess) { 89 if (time_zone_binary_mount_result != ResultSuccess) {
96 return; 90 return;
97 } 91 }
98 // out_path = fmt::format("{}:/version.txt", "TimeZoneBinary"); 92 // out_path = fmt::format("{}:/version.txt", "TimeZoneBinary");
99 out_path = "/version.txt"; 93 out_path = "/version.txt";
100} 94}
101 95
102void GetTimeZoneZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name) { 96void TimeZoneBinary::GetTimeZonePath(std::string& out_path,
103 if (g_time_zone_binary_mount_result != ResultSuccess) { 97 const Service::PSC::Time::LocationName& name) {
98 if (time_zone_binary_mount_result != ResultSuccess) {
104 return; 99 return;
105 } 100 }
106 // out_path = fmt::format("{}:/zoneinfo/{}", "TimeZoneBinary", name); 101 // out_path = fmt::format("{}:/zoneinfo/{}", "TimeZoneBinary", name);
107 out_path = fmt::format("/zoneinfo/{}", name.data()); 102 out_path = fmt::format("/zoneinfo/{}", name.data());
108} 103}
109 104
110bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name) { 105bool TimeZoneBinary::IsValid(const Service::PSC::Time::LocationName& name) {
111 std::string path{}; 106 std::string path{};
112 GetTimeZoneZonePath(path, name); 107 GetTimeZonePath(path, name);
113 108
114 auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)}; 109 auto vfs_file{time_zone_binary_romfs->GetFileRelative(path)};
115 if (!vfs_file) { 110 if (!vfs_file) {
116 LOG_INFO(Service_Time, "Could not find timezone file {}", path); 111 LOG_INFO(Service_Time, "Could not find timezone file {}", path);
117 return false; 112 return false;
@@ -119,19 +114,19 @@ bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name) {
119 return vfs_file->GetSize() != 0; 114 return vfs_file->GetSize() != 0;
120} 115}
121 116
122u32 GetTimeZoneCount() { 117u32 TimeZoneBinary::GetTimeZoneCount() {
123 std::string path{}; 118 std::string path{};
124 GetTimeZoneBinaryListPath(path); 119 GetListPath(path);
125 120
126 size_t bytes_read{}; 121 size_t bytes_read{};
127 if (TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space, 0x2800, path) != ResultSuccess) { 122 if (Read(bytes_read, time_zone_scratch_space, 0x2800, path) != ResultSuccess) {
128 return 0; 123 return 0;
129 } 124 }
130 if (bytes_read == 0) { 125 if (bytes_read == 0) {
131 return 0; 126 return 0;
132 } 127 }
133 128
134 auto chars = std::span(reinterpret_cast<char*>(g_time_zone_scratch_space.data()), bytes_read); 129 auto chars = std::span(reinterpret_cast<char*>(time_zone_scratch_space.data()), bytes_read);
135 u32 count{}; 130 u32 count{};
136 for (auto chr : chars) { 131 for (auto chr : chars) {
137 if (chr == '\n') { 132 if (chr == '\n') {
@@ -141,50 +136,47 @@ u32 GetTimeZoneCount() {
141 return count; 136 return count;
142} 137}
143 138
144Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version) { 139Result TimeZoneBinary::GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version) {
145 std::string path{}; 140 std::string path{};
146 GetTimeZoneBinaryVersionPath(path); 141 GetVersionPath(path);
147 142
148 auto rule_version_buffer{std::span(reinterpret_cast<u8*>(&out_rule_version), 143 auto rule_version_buffer{std::span(reinterpret_cast<u8*>(&out_rule_version),
149 sizeof(Service::PSC::Time::RuleVersion))}; 144 sizeof(Service::PSC::Time::RuleVersion))};
150 size_t bytes_read{}; 145 size_t bytes_read{};
151 R_TRY(TimeZoneReadBinary(bytes_read, rule_version_buffer, rule_version_buffer.size_bytes(), 146 R_TRY(Read(bytes_read, rule_version_buffer, rule_version_buffer.size_bytes(), path));
152 path));
153 147
154 rule_version_buffer[bytes_read] = 0; 148 rule_version_buffer[bytes_read] = 0;
155 R_SUCCEED(); 149 R_SUCCEED();
156} 150}
157 151
158Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size, 152Result TimeZoneBinary::GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
159 const Service::PSC::Time::LocationName& name) { 153 const Service::PSC::Time::LocationName& name) {
160 std::string path{}; 154 std::string path{};
161 GetTimeZoneZonePath(path, name); 155 GetTimeZonePath(path, name);
162 156
163 size_t bytes_read{}; 157 size_t bytes_read{};
164 R_TRY(TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space, 158 R_TRY(Read(bytes_read, time_zone_scratch_space, time_zone_scratch_space.size(), path));
165 g_time_zone_scratch_space.size(), path));
166 159
167 out_rule = std::span(g_time_zone_scratch_space.data(), bytes_read); 160 out_rule = std::span(time_zone_scratch_space.data(), bytes_read);
168 out_rule_size = bytes_read; 161 out_rule_size = bytes_read;
169 R_SUCCEED(); 162 R_SUCCEED();
170} 163}
171 164
172Result GetTimeZoneLocationList(u32& out_count, 165Result TimeZoneBinary::GetTimeZoneLocationList(
173 std::span<Service::PSC::Time::LocationName> out_names, 166 u32& out_count, std::span<Service::PSC::Time::LocationName> out_names, size_t max_names,
174 size_t max_names, u32 index) { 167 u32 index) {
175 std::string path{}; 168 std::string path{};
176 GetTimeZoneBinaryListPath(path); 169 GetListPath(path);
177 170
178 size_t bytes_read{}; 171 size_t bytes_read{};
179 R_TRY(TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space, 172 R_TRY(Read(bytes_read, time_zone_scratch_space, time_zone_scratch_space.size(), path));
180 g_time_zone_scratch_space.size(), path));
181 173
182 out_count = 0; 174 out_count = 0;
183 R_SUCCEED_IF(bytes_read == 0); 175 R_SUCCEED_IF(bytes_read == 0);
184 176
185 Service::PSC::Time::LocationName current_name{}; 177 Service::PSC::Time::LocationName current_name{};
186 size_t current_name_len{}; 178 size_t current_name_len{};
187 std::span<const u8> chars{g_time_zone_scratch_space}; 179 std::span<const u8> chars{time_zone_scratch_space};
188 u32 name_count{}; 180 u32 name_count{};
189 181
190 for (auto chr : chars) { 182 for (auto chr : chars) {
diff --git a/src/core/hle/service/glue/time/time_zone_binary.h b/src/core/hle/service/glue/time/time_zone_binary.h
index 9d0a8dfe9..135da631f 100755
--- a/src/core/hle/service/glue/time/time_zone_binary.h
+++ b/src/core/hle/service/glue/time/time_zone_binary.h
@@ -6,6 +6,7 @@
6#include <span> 6#include <span>
7#include <string> 7#include <string>
8#include <string_view> 8#include <string_view>
9#include <vector>
9 10
10#include "core/hle/service/psc/time/common.h" 11#include "core/hle/service/psc/time/common.h"
11 12
@@ -15,18 +16,34 @@ class System;
15 16
16namespace Service::Glue::Time { 17namespace Service::Glue::Time {
17 18
18void ResetTimeZoneBinary(); 19class TimeZoneBinary {
19Result MountTimeZoneBinary(Core::System& system); 20public:
20void GetTimeZoneBinaryListPath(std::string& out_path); 21 explicit TimeZoneBinary(Core::System& system_)
21void GetTimeZoneBinaryVersionPath(std::string& out_path); 22 : time_zone_scratch_space(0x2800, 0), system{system_} {}
22void GetTimeZoneZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name); 23
23bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name); 24 Result Mount();
24u32 GetTimeZoneCount(); 25 bool IsValid(const Service::PSC::Time::LocationName& name);
25Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version); 26 u32 GetTimeZoneCount();
26Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size, 27 Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version);
27 const Service::PSC::Time::LocationName& name); 28 Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
28Result GetTimeZoneLocationList(u32& out_count, 29 const Service::PSC::Time::LocationName& name);
29 std::span<Service::PSC::Time::LocationName> out_names, 30 Result GetTimeZoneLocationList(u32& out_count,
30 size_t max_names, u32 index); 31 std::span<Service::PSC::Time::LocationName> out_names,
32 size_t max_names, u32 index);
33
34private:
35 void Reset();
36 Result Read(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
37 std::string_view path);
38 void GetListPath(std::string& out_path);
39 void GetVersionPath(std::string& out_path);
40 void GetTimeZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name);
41
42 FileSys::VirtualDir time_zone_binary_romfs{};
43 Result time_zone_binary_mount_result{ResultUnknown};
44 std::vector<u8> time_zone_scratch_space;
45
46 Core::System& system;
47};
31 48
32} // namespace Service::Glue::Time 49} // namespace Service::Glue::Time
diff --git a/src/core/hle/service/glue/time/worker.cpp b/src/core/hle/service/glue/time/worker.cpp
index b6bbd7965..1dab3e9dc 100755
--- a/src/core/hle/service/glue/time/worker.cpp
+++ b/src/core/hle/service/glue/time/worker.cpp
@@ -16,23 +16,6 @@
16#include "core/hle/service/sm/sm.h" 16#include "core/hle/service/sm/sm.h"
17 17
18namespace Service::Glue::Time { 18namespace Service::Glue::Time {
19namespace {
20
21bool g_ig_report_network_clock_context_set{};
22Service::PSC::Time::SystemClockContext g_report_network_clock_context{};
23bool g_ig_report_ephemeral_clock_context_set{};
24Service::PSC::Time::SystemClockContext g_report_ephemeral_clock_context{};
25
26template <typename T>
27T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys,
28 const char* category, const char* name) {
29 T v{};
30 auto res = set_sys->GetSettingsItemValueImpl(v, category, name);
31 ASSERT(res == ResultSuccess);
32 return v;
33}
34
35} // namespace
36 19
37TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource, 20TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource,
38 FileTimestampWorker& file_timestamp_worker) 21 FileTimestampWorker& file_timestamp_worker)
@@ -43,11 +26,6 @@ TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady
43 "Glue:TimeWorker:SteadyClockTimerEvent")}, 26 "Glue:TimeWorker:SteadyClockTimerEvent")},
44 m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")}, 27 m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")},
45 m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} { 28 m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} {
46 g_ig_report_network_clock_context_set = false;
47 g_report_network_clock_context = {};
48 g_ig_report_ephemeral_clock_context_set = false;
49 g_report_ephemeral_clock_context = {};
50
51 m_timer_steady_clock_timing_event = Core::Timing::CreateEvent( 29 m_timer_steady_clock_timing_event = Core::Timing::CreateEvent(
52 "Time::SteadyClockEvent", 30 "Time::SteadyClockEvent",
53 [this](s64 time, 31 [this](s64 time,
@@ -82,6 +60,14 @@ TimeWorker::~TimeWorker() {
82 m_ctx.CloseEvent(m_timer_file_system); 60 m_ctx.CloseEvent(m_timer_file_system);
83} 61}
84 62
63template <typename T>
64T TimeWorker::GetSettingsItemValue(const std::string& category, const std::string& name) {
65 T v{};
66 auto res = m_set_sys->GetSettingsItemValueImpl(v, category, name);
67 ASSERT(res == ResultSuccess);
68 return v;
69}
70
85void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> time_sm, 71void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> time_sm,
86 std::shared_ptr<Service::Set::ISystemSettingsServer> set_sys) { 72 std::shared_ptr<Service::Set::ISystemSettingsServer> set_sys) {
87 m_set_sys = std::move(set_sys); 73 m_set_sys = std::move(set_sys);
@@ -91,8 +77,8 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t
91 77
92 m_alarm_worker.Initialize(m_time_m); 78 m_alarm_worker.Initialize(m_time_m);
93 79
94 auto steady_clock_interval_m = GetSettingsItemValue<s32>( 80 auto steady_clock_interval_m =
95 m_set_sys, "time", "standard_steady_clock_rtc_update_interval_minutes"); 81 GetSettingsItemValue<s32>("time", "standard_steady_clock_rtc_update_interval_minutes");
96 82
97 auto one_minute_ns{ 83 auto one_minute_ns{
98 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::minutes(1)).count()}; 84 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::minutes(1)).count()};
@@ -102,8 +88,7 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t
102 std::chrono::nanoseconds(steady_clock_interval_ns), 88 std::chrono::nanoseconds(steady_clock_interval_ns),
103 m_timer_steady_clock_timing_event); 89 m_timer_steady_clock_timing_event);
104 90
105 auto fs_notify_time_s = 91 auto fs_notify_time_s = GetSettingsItemValue<s32>("time", "notify_time_to_fs_interval_seconds");
106 GetSettingsItemValue<s32>(m_set_sys, "time", "notify_time_to_fs_interval_seconds");
107 auto one_second_ns{ 92 auto one_second_ns{
108 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count()}; 93 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count()};
109 s64 fs_notify_time_ns{fs_notify_time_s * one_second_ns}; 94 s64 fs_notify_time_ns{fs_notify_time_s * one_second_ns};
@@ -218,14 +203,14 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
218 } 203 }
219 204
220 [[maybe_unused]] auto offset_before{ 205 [[maybe_unused]] auto offset_before{
221 g_ig_report_network_clock_context_set ? g_report_network_clock_context.offset : 0}; 206 m_ig_report_network_clock_context_set ? m_report_network_clock_context.offset : 0};
222 // TODO system report "standard_netclock_operation" 207 // TODO system report "standard_netclock_operation"
223 // "clock_time" = time 208 // "clock_time" = time
224 // "context_offset_before" = offset_before 209 // "context_offset_before" = offset_before
225 // "context_offset_after" = context.offset 210 // "context_offset_after" = context.offset
226 g_report_network_clock_context = context; 211 m_report_network_clock_context = context;
227 if (!g_ig_report_network_clock_context_set) { 212 if (!m_ig_report_network_clock_context_set) {
228 g_ig_report_network_clock_context_set = true; 213 m_ig_report_network_clock_context_set = true;
229 } 214 }
230 215
231 m_file_timestamp_worker.SetFilesystemPosixTime(); 216 m_file_timestamp_worker.SetFilesystemPosixTime();
@@ -247,16 +232,16 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
247 break; 232 break;
248 } 233 }
249 234
250 [[maybe_unused]] auto offset_before{g_ig_report_ephemeral_clock_context_set 235 [[maybe_unused]] auto offset_before{m_ig_report_ephemeral_clock_context_set
251 ? g_report_ephemeral_clock_context.offset 236 ? m_report_ephemeral_clock_context.offset
252 : 0}; 237 : 0};
253 // TODO system report "ephemeral_netclock_operation" 238 // TODO system report "ephemeral_netclock_operation"
254 // "clock_time" = time 239 // "clock_time" = time
255 // "context_offset_before" = offset_before 240 // "context_offset_before" = offset_before
256 // "context_offset_after" = context.offset 241 // "context_offset_after" = context.offset
257 g_report_ephemeral_clock_context = context; 242 m_report_ephemeral_clock_context = context;
258 if (!g_ig_report_ephemeral_clock_context_set) { 243 if (!m_ig_report_ephemeral_clock_context_set) {
259 g_ig_report_ephemeral_clock_context_set = true; 244 m_ig_report_ephemeral_clock_context_set = true;
260 } 245 }
261 break; 246 break;
262 } 247 }
diff --git a/src/core/hle/service/glue/time/worker.h b/src/core/hle/service/glue/time/worker.h
index 75e5c4d0f..69904e674 100755
--- a/src/core/hle/service/glue/time/worker.h
+++ b/src/core/hle/service/glue/time/worker.h
@@ -34,6 +34,9 @@ public:
34 void StartThread(); 34 void StartThread();
35 35
36private: 36private:
37 template <typename T>
38 T GetSettingsItemValue(const std::string& category, const std::string& name);
39
37 void ThreadFunc(std::stop_token stop_token); 40 void ThreadFunc(std::stop_token stop_token);
38 41
39 Core::System& m_system; 42 Core::System& m_system;
@@ -59,6 +62,11 @@ private:
59 std::shared_ptr<Core::Timing::EventType> m_timer_file_system_timing_event; 62 std::shared_ptr<Core::Timing::EventType> m_timer_file_system_timing_event;
60 AlarmWorker m_alarm_worker; 63 AlarmWorker m_alarm_worker;
61 PmStateChangeHandler m_pm_state_change_handler; 64 PmStateChangeHandler m_pm_state_change_handler;
65
66 bool m_ig_report_network_clock_context_set{};
67 Service::PSC::Time::SystemClockContext m_report_network_clock_context{};
68 bool m_ig_report_ephemeral_clock_context_set{};
69 Service::PSC::Time::SystemClockContext m_report_ephemeral_clock_context{};
62}; 70};
63 71
64} // namespace Service::Glue::Time 72} // namespace Service::Glue::Time
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp
index 0b41bbcb9..3d898725e 100755
--- a/src/core/hle/service/server_manager.cpp
+++ b/src/core/hle/service/server_manager.cpp
@@ -93,13 +93,19 @@ ServerManager::~ServerManager() {
93 m_threads.clear(); 93 m_threads.clear();
94 94
95 // Clean up ports. 95 // Clean up ports.
96 for (auto it = m_servers.begin(); it != m_servers.end(); it = m_servers.erase(it)) { 96 auto port_it = m_servers.begin();
97 delete std::addressof(*it); 97 while (port_it != m_servers.end()) {
98 auto* const port = std::addressof(*port_it);
99 port_it = m_servers.erase(port_it);
100 delete port;
98 } 101 }
99 102
100 // Clean up sessions. 103 // Clean up sessions.
101 for (auto it = m_sessions.begin(); it != m_sessions.end(); it = m_sessions.erase(it)) { 104 auto session_it = m_sessions.begin();
102 delete std::addressof(*it); 105 while (session_it != m_sessions.end()) {
106 auto* const session = std::addressof(*session_it);
107 session_it = m_sessions.erase(session_it);
108 delete session;
103 } 109 }
104 110
105 // Close wakeup event. 111 // Close wakeup event.
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index e8430506e..bcaa3d472 100755
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -36,22 +36,23 @@ std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) {
36} // namespace 36} // namespace
37 37
38FileType IdentifyFile(FileSys::VirtualFile file) { 38FileType IdentifyFile(FileSys::VirtualFile file) {
39 if (const auto romdir_type = IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) { 39 if (const auto nsp_type = IdentifyFileLoader<AppLoader_NSP>(file)) {
40 return *romdir_type; 40 return *nsp_type;
41 } else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) { 41 } else if (const auto xci_type = IdentifyFileLoader<AppLoader_XCI>(file)) {
42 return *nso_type; 42 return *xci_type;
43 } else if (const auto nro_type = IdentifyFileLoader<AppLoader_NRO>(file)) { 43 } else if (const auto nro_type = IdentifyFileLoader<AppLoader_NRO>(file)) {
44 return *nro_type; 44 return *nro_type;
45 } else if (const auto nca_type = IdentifyFileLoader<AppLoader_NCA>(file)) { 45 } else if (const auto nca_type = IdentifyFileLoader<AppLoader_NCA>(file)) {
46 return *nca_type; 46 return *nca_type;
47 } else if (const auto xci_type = IdentifyFileLoader<AppLoader_XCI>(file)) {
48 return *xci_type;
49 } else if (const auto nax_type = IdentifyFileLoader<AppLoader_NAX>(file)) { 47 } else if (const auto nax_type = IdentifyFileLoader<AppLoader_NAX>(file)) {
50 return *nax_type; 48 return *nax_type;
51 } else if (const auto nsp_type = IdentifyFileLoader<AppLoader_NSP>(file)) {
52 return *nsp_type;
53 } else if (const auto kip_type = IdentifyFileLoader<AppLoader_KIP>(file)) { 49 } else if (const auto kip_type = IdentifyFileLoader<AppLoader_KIP>(file)) {
54 return *kip_type; 50 return *kip_type;
51 } else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) {
52 return *nso_type;
53 } else if (const auto romdir_type =
54 IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) {
55 return *romdir_type;
55 } else { 56 } else {
56 return FileType::Unknown; 57 return FileType::Unknown;
57 } 58 }
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index c5fa63229..d7e76324f 100755
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -71,7 +71,7 @@ const char* GetType(GLenum type) {
71 71
72void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, 72void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
73 const GLchar* message, const void* user_param) { 73 const GLchar* message, const void* user_param) {
74 const char format[] = "{} {} {}: {}"; 74 constexpr std::string_view format = "{} {} {}: {}";
75 const char* const str_source = GetSource(source); 75 const char* const str_source = GetSource(source);
76 const char* const str_type = GetType(type); 76 const char* const str_type = GetType(type);
77 77
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index f11d0ba16..b4e68764c 100755
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -40,6 +40,12 @@ constexpr std::array DEPTH24_UNORM_STENCIL8_UINT{
40 VK_FORMAT_UNDEFINED, 40 VK_FORMAT_UNDEFINED,
41}; 41};
42 42
43constexpr std::array DEPTH24_UNORM_DONTCARE8{
44 VK_FORMAT_D32_SFLOAT,
45 VK_FORMAT_D16_UNORM,
46 VK_FORMAT_UNDEFINED,
47};
48
43constexpr std::array DEPTH16_UNORM_STENCIL8_UINT{ 49constexpr std::array DEPTH16_UNORM_STENCIL8_UINT{
44 VK_FORMAT_D24_UNORM_S8_UINT, 50 VK_FORMAT_D24_UNORM_S8_UINT,
45 VK_FORMAT_D32_SFLOAT_S8_UINT, 51 VK_FORMAT_D32_SFLOAT_S8_UINT,
@@ -95,6 +101,8 @@ constexpr const VkFormat* GetFormatAlternatives(VkFormat format) {
95 return Alternatives::STENCIL8_UINT.data(); 101 return Alternatives::STENCIL8_UINT.data();
96 case VK_FORMAT_D24_UNORM_S8_UINT: 102 case VK_FORMAT_D24_UNORM_S8_UINT:
97 return Alternatives::DEPTH24_UNORM_STENCIL8_UINT.data(); 103 return Alternatives::DEPTH24_UNORM_STENCIL8_UINT.data();
104 case VK_FORMAT_X8_D24_UNORM_PACK32:
105 return Alternatives::DEPTH24_UNORM_DONTCARE8.data();
98 case VK_FORMAT_D16_UNORM_S8_UINT: 106 case VK_FORMAT_D16_UNORM_S8_UINT:
99 return Alternatives::DEPTH16_UNORM_STENCIL8_UINT.data(); 107 return Alternatives::DEPTH16_UNORM_STENCIL8_UINT.data();
100 case VK_FORMAT_B5G6R5_UNORM_PACK16: 108 case VK_FORMAT_B5G6R5_UNORM_PACK16: