early-access version 4175

This commit is contained in:
pineappleEA 2024-02-27 18:06:04 +01:00
parent f6fd2265b1
commit 90ca646c0d
24 changed files with 225 additions and 213 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access
=============
This is the source code for early-access 4174.
This is the source code for early-access 4175.
## Legal Notice

View file

@ -343,7 +343,7 @@ void SetColorConsoleBackendEnabled(bool enabled) {
}
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, const char* format,
unsigned int line_num, const char* function, fmt::string_view format,
const fmt::format_args& args) {
if (!initialization_in_progress_suppress_logging) {
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function,

View file

@ -24,12 +24,12 @@ constexpr const char* TrimSourcePath(std::string_view source) {
/// Logs a message to the global logger, using fmt
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, const char* format,
unsigned int line_num, const char* function, fmt::string_view format,
const fmt::format_args& args);
template <typename... Args>
void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, const char* format, const Args&... args) {
const char* function, fmt::format_string<Args...> format, const Args&... args) {
FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format,
fmt::make_format_args(args...));
}

View file

@ -31,8 +31,8 @@ AesXtsStorage::AesXtsStorage(VirtualFile base, const void* key1, const void* key
ASSERT(iv_size == IvSize);
ASSERT(Common::IsAligned(m_block_size, AesBlockSize));
std::memcpy(m_key.data() + 0, key1, KeySize);
std::memcpy(m_key.data() + 0x10, key2, KeySize);
std::memcpy(m_key.data() + 0, key1, KeySize / 2);
std::memcpy(m_key.data() + 0x10, key2, KeySize / 2);
std::memcpy(m_iv.data(), iv, IvSize);
m_cipher.emplace(m_key, Core::Crypto::Mode::XTS);

View file

@ -105,12 +105,4 @@ VirtualDir PartitionFilesystem::GetParentDirectory() const {
return nullptr;
}
void PartitionFilesystem::PrintDebugInfo() const {
LOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic);
LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries);
for (u32 i = 0; i < pfs_header.num_entries; i++) {
LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes)", i,
pfs_files[i]->GetName(), pfs_files[i]->GetSize());
}
}
} // namespace FileSys

View file

@ -35,7 +35,6 @@ public:
std::vector<VirtualDir> GetSubdirectories() const override;
std::string GetName() const override;
VirtualDir GetParentDirectory() const override;
void PrintDebugInfo() const;
private:
struct Header {

View file

@ -9,9 +9,8 @@
namespace FileSys {
OffsetVfsFile::OffsetVfsFile(VirtualFile file_, std::size_t size_, std::size_t offset_,
std::string name_, VirtualDir parent_)
: file(file_), offset(offset_), size(size_), name(std::move(name_)),
parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
std::string name_)
: file(file_), offset(offset_), size(size_), name(std::move(name_)) {}
OffsetVfsFile::~OffsetVfsFile() = default;
@ -37,7 +36,7 @@ bool OffsetVfsFile::Resize(std::size_t new_size) {
}
VirtualDir OffsetVfsFile::GetContainingDirectory() const {
return parent;
return nullptr;
}
bool OffsetVfsFile::IsWritable() const {

View file

@ -16,7 +16,7 @@ namespace FileSys {
class OffsetVfsFile : public VfsFile {
public:
OffsetVfsFile(VirtualFile file, std::size_t size, std::size_t offset = 0,
std::string new_name = "", VirtualDir new_parent = nullptr);
std::string new_name = "");
~OffsetVfsFile() override;
std::string GetName() const override;
@ -44,7 +44,6 @@ private:
std::size_t offset;
std::size_t size;
std::string name;
VirtualDir parent;
};
} // namespace FileSys

View file

@ -76,6 +76,7 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const {
}
VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::optional<u64> size,
std::optional<std::string> parent_path,
OpenMode perms) {
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
std::scoped_lock lk{list_lock};
@ -94,14 +95,14 @@ VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::op
this->InsertReferenceIntoListLocked(*reference);
auto file = std::shared_ptr<RealVfsFile>(
new RealVfsFile(*this, std::move(reference), path, perms, size));
new RealVfsFile(*this, std::move(reference), path, perms, size, std::move(parent_path)));
cache[path] = file;
return file;
}
VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, OpenMode perms) {
return OpenFileFromEntry(path_, {}, perms);
return OpenFileFromEntry(path_, {}, {}, perms);
}
VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, OpenMode perms) {
@ -268,10 +269,11 @@ void RealVfsFilesystem::RemoveReferenceFromListLocked(FileReference& reference)
}
RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_,
const std::string& path_, OpenMode perms_, std::optional<u64> size_)
const std::string& path_, OpenMode perms_, std::optional<u64> size_,
std::optional<std::string> parent_path_)
: base(base_), reference(std::move(reference_)), path(path_),
parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponentsCopy(path_)),
size(size_), perms(perms_) {}
parent_path(parent_path_ ? std::move(*parent_path_) : FS::GetParentPath(path_)),
path_components(FS::SplitPathComponentsCopy(path_)), size(size_), perms(perms_) {}
RealVfsFile::~RealVfsFile() {
base.DropReference(std::move(reference));
@ -348,7 +350,7 @@ std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>(
&out](const std::filesystem::directory_entry& entry) {
const auto full_path_string = FS::PathToUTF8String(entry.path());
out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), perms));
out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), path, perms));
return true;
};

View file

@ -62,6 +62,7 @@ private:
private:
friend class RealVfsDirectory;
VirtualFile OpenFileFromEntry(std::string_view path, std::optional<u64> size,
std::optional<std::string> parent_path,
OpenMode perms = OpenMode::Read);
private:
@ -91,7 +92,7 @@ public:
private:
RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
const std::string& path, OpenMode perms = OpenMode::Read,
std::optional<u64> size = {});
std::optional<u64> size = {}, std::optional<std::string> parent_path = {});
RealVfsFilesystem& base;
std::unique_ptr<FileReference> reference;

View file

@ -11,7 +11,6 @@
#include "core/file_sys/vfs/vfs.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/service/glue/time/manager.h"
#include "core/hle/service/glue/time/time_zone_binary.h"
#include "core/hle/service/psc/time/service_manager.h"
#include "core/hle/service/psc/time/static.h"
#include "core/hle/service/psc/time/system_clock.h"
@ -20,8 +19,8 @@
#include "core/hle/service/sm/sm.h"
namespace Service::Glue::Time {
namespace {
s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
static s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
constexpr auto is_leap = [](s32 year) -> bool {
return (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0));
};
@ -50,7 +49,8 @@ s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
return epoch_s - 62135683200ll;
}
s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) {
static s64 GetEpochTimeFromInitialYear(
std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) {
s32 year{2000};
set_sys->GetSettingsItemValueImpl(year, "time", "standard_user_clock_initial_year");
@ -65,31 +65,32 @@ s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsSer
return CalendarTimeToEpoch(calendar);
}
Service::PSC::Time::LocationName GetTimeZoneString(Service::PSC::Time::LocationName& in_name) {
static Service::PSC::Time::LocationName GetTimeZoneString(
TimeZoneBinary& time_zone_binary, Service::PSC::Time::LocationName& in_name) {
auto configured_zone = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue());
Service::PSC::Time::LocationName configured_name{};
std::memcpy(configured_name.data(), configured_zone.data(),
std::min(configured_name.size(), configured_zone.size()));
if (!IsTimeZoneBinaryValid(configured_name)) {
if (!time_zone_binary.IsValid(configured_name)) {
configured_zone = Common::TimeZone::FindSystemTimeZone();
configured_name = {};
std::memcpy(configured_name.data(), configured_zone.data(),
std::min(configured_name.size(), configured_zone.size()));
}
ASSERT_MSG(IsTimeZoneBinaryValid(configured_name), "Invalid time zone {}!",
ASSERT_MSG(time_zone_binary.IsValid(configured_name), "Invalid time zone {}!",
configured_name.data());
return configured_name;
}
} // namespace
TimeManager::TimeManager(Core::System& system)
: m_steady_clock_resource{system}, m_worker{system, m_steady_clock_resource,
m_file_timestamp_worker} {
: m_steady_clock_resource{system}, m_time_zone_binary{system}, m_worker{
system,
m_steady_clock_resource,
m_file_timestamp_worker} {
m_time_m =
system.ServiceManager().GetService<Service::PSC::Time::ServiceManager>("time:m", true);
@ -99,7 +100,7 @@ TimeManager::TimeManager(Core::System& system)
m_set_sys =
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
res = MountTimeZoneBinary(system);
res = m_time_zone_binary.Mount();
ASSERT(res == ResultSuccess);
m_worker.Initialize(m_time_sm, m_set_sys);
@ -187,10 +188,6 @@ TimeManager::TimeManager(Core::System& system)
}
}
TimeManager::~TimeManager() {
ResetTimeZoneBinary();
}
Result TimeManager::SetupStandardSteadyClockCore() {
Common::UUID external_clock_source_id{};
auto res = m_set_sys->GetExternalSteadyClockSourceId(&external_clock_source_id);
@ -236,7 +233,7 @@ Result TimeManager::SetupTimeZoneServiceCore() {
auto res = m_set_sys->GetDeviceTimeZoneLocationName(&name);
ASSERT(res == ResultSuccess);
auto configured_zone = GetTimeZoneString(name);
auto configured_zone = GetTimeZoneString(m_time_zone_binary, name);
if (configured_zone != name) {
m_set_sys->SetDeviceTimeZoneLocationName(configured_zone);
@ -254,13 +251,13 @@ Result TimeManager::SetupTimeZoneServiceCore() {
res = m_set_sys->GetDeviceTimeZoneLocationUpdatedTime(&time_point);
ASSERT(res == ResultSuccess);
auto location_count = GetTimeZoneCount();
auto location_count = m_time_zone_binary.GetTimeZoneCount();
Service::PSC::Time::RuleVersion rule_version{};
GetTimeZoneVersion(rule_version);
m_time_zone_binary.GetTimeZoneVersion(rule_version);
std::span<const u8> rule_buffer{};
size_t rule_size{};
res = GetTimeZoneRule(rule_buffer, rule_size, name);
res = m_time_zone_binary.GetTimeZoneRule(rule_buffer, rule_size, name);
ASSERT(res == ResultSuccess);
res = m_time_m->SetupTimeZoneServiceCore(name, rule_version, location_count, time_point,

View file

@ -10,6 +10,7 @@
#include "core/file_sys/vfs/vfs_types.h"
#include "core/hle/service/glue/time/file_timestamp_worker.h"
#include "core/hle/service/glue/time/standard_steady_clock_resource.h"
#include "core/hle/service/glue/time/time_zone_binary.h"
#include "core/hle/service/glue/time/worker.h"
#include "core/hle/service/service.h"
@ -26,7 +27,7 @@ namespace Service::Glue::Time {
class TimeManager {
public:
explicit TimeManager(Core::System& system);
~TimeManager();
~TimeManager() = default;
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
@ -34,6 +35,7 @@ public:
std::shared_ptr<Service::PSC::Time::StaticService> m_time_sm{};
StandardSteadyClockResource m_steady_clock_resource;
FileTimestampWorker m_file_timestamp_worker;
TimeZoneBinary m_time_zone_binary;
TimeWorker m_worker;
private:

View file

@ -26,8 +26,9 @@ StaticService::StaticService(Core::System& system_,
std::shared_ptr<TimeManager> time, const char* name)
: ServiceFramework{system_, name}, m_system{system_}, m_time_m{time->m_time_m},
m_setup_info{setup_info}, m_time_sm{time->m_time_sm},
m_file_timestamp_worker{time->m_file_timestamp_worker}, m_standard_steady_clock_resource{
time->m_steady_clock_resource} {
m_file_timestamp_worker{time->m_file_timestamp_worker},
m_standard_steady_clock_resource{time->m_steady_clock_resource},
m_time_zone_binary{time->m_time_zone_binary} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"},
@ -106,7 +107,7 @@ Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_servi
*out_service = std::make_shared<TimeZoneService>(
m_system, m_file_timestamp_worker, m_setup_info.can_write_timezone_device_location,
m_time_zone);
m_time_zone_binary, m_time_zone);
R_SUCCEED();
}

View file

@ -80,5 +80,6 @@ private:
std::shared_ptr<Service::PSC::Time::TimeZoneService> m_time_zone;
FileTimestampWorker& m_file_timestamp_worker;
StandardSteadyClockResource& m_standard_steady_clock_resource;
TimeZoneBinary& m_time_zone_binary;
};
} // namespace Service::Glue::Time

View file

@ -15,19 +15,16 @@
#include "core/hle/service/sm/sm.h"
namespace Service::Glue::Time {
namespace {
static std::mutex g_list_mutex;
static Common::IntrusiveListBaseTraits<Service::PSC::Time::OperationEvent>::ListType g_list_nodes{};
} // namespace
TimeZoneService::TimeZoneService(
Core::System& system_, FileTimestampWorker& file_timestamp_worker,
bool can_write_timezone_device_location,
bool can_write_timezone_device_location, TimeZoneBinary& time_zone_binary,
std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service)
: ServiceFramework{system_, "ITimeZoneService"}, m_system{system},
m_can_write_timezone_device_location{can_write_timezone_device_location},
m_file_timestamp_worker{file_timestamp_worker},
m_wrapped_service{std::move(time_zone_service)}, m_operation_event{m_system} {
m_file_timestamp_worker{file_timestamp_worker}, m_wrapped_service{std::move(
time_zone_service)},
m_operation_event{m_system}, m_time_zone_binary{time_zone_binary} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"},
@ -48,7 +45,6 @@ TimeZoneService::TimeZoneService(
// clang-format on
RegisterHandlers(functions);
g_list_nodes.clear();
m_set_sys =
m_system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
}
@ -69,13 +65,13 @@ Result TimeZoneService::SetDeviceLocationName(
LOG_DEBUG(Service_Time, "called. location_name={}", location_name);
R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied);
R_UNLESS(IsTimeZoneBinaryValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound);
R_UNLESS(m_time_zone_binary.IsValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound);
std::scoped_lock l{m_mutex};
std::span<const u8> binary{};
size_t binary_size{};
R_TRY(GetTimeZoneRule(binary, binary_size, location_name))
R_TRY(m_time_zone_binary.GetTimeZoneRule(binary, binary_size, location_name))
R_TRY(m_wrapped_service->SetDeviceLocationNameWithTimeZoneRule(location_name, binary));
@ -88,8 +84,8 @@ Result TimeZoneService::SetDeviceLocationName(
m_set_sys->SetDeviceTimeZoneLocationName(name);
m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(time_point);
std::scoped_lock m{g_list_mutex};
for (auto& operation_event : g_list_nodes) {
std::scoped_lock m{m_list_mutex};
for (auto& operation_event : m_list_nodes) {
operation_event.m_event->Signal();
}
R_SUCCEED();
@ -112,7 +108,8 @@ Result TimeZoneService::LoadLocationNameList(
};
std::scoped_lock l{m_mutex};
R_RETURN(GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index));
R_RETURN(
m_time_zone_binary.GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index));
}
Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule,
@ -122,7 +119,7 @@ Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule,
std::scoped_lock l{m_mutex};
std::span<const u8> binary{};
size_t binary_size{};
R_TRY(GetTimeZoneRule(binary, binary_size, name))
R_TRY(m_time_zone_binary.GetTimeZoneRule(binary, binary_size, name))
R_RETURN(m_wrapped_service->ParseTimeZoneBinary(out_rule, binary));
}
@ -174,7 +171,7 @@ Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle(
m_operation_event.m_ctx.CreateEvent("Psc:TimeZoneService:OperationEvent");
operation_event_initialized = true;
std::scoped_lock l{m_mutex};
g_list_nodes.push_back(m_operation_event);
m_list_nodes.push_back(m_operation_event);
}
*out_event = &m_operation_event.m_event->GetReadableEvent();

View file

@ -32,6 +32,7 @@ class TimeZoneService;
namespace Service::Glue::Time {
class FileTimestampWorker;
class TimeZoneBinary;
class TimeZoneService final : public ServiceFramework<TimeZoneService> {
using InRule = InLargeData<Tz::Rule, BufferAttr_HipcMapAlias>;
@ -40,7 +41,7 @@ class TimeZoneService final : public ServiceFramework<TimeZoneService> {
public:
explicit TimeZoneService(
Core::System& system, FileTimestampWorker& file_timestamp_worker,
bool can_write_timezone_device_location,
bool can_write_timezone_device_location, TimeZoneBinary& time_zone_binary,
std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service);
~TimeZoneService() override;
@ -85,6 +86,10 @@ private:
std::mutex m_mutex;
bool operation_event_initialized{};
Service::PSC::Time::OperationEvent m_operation_event;
TimeZoneBinary& m_time_zone_binary;
std::mutex m_list_mutex;
Common::IntrusiveListBaseTraits<Service::PSC::Time::OperationEvent>::ListType m_list_nodes{};
};
} // namespace Service::Glue::Time

View file

@ -12,18 +12,58 @@
#include "core/hle/service/glue/time/time_zone_binary.h"
namespace Service::Glue::Time {
namespace {
constexpr u64 TimeZoneBinaryId = 0x10000000000080E;
static FileSys::VirtualDir g_time_zone_binary_romfs{};
static Result g_time_zone_binary_mount_result{ResultUnknown};
static std::vector<u8> g_time_zone_scratch_space(0x2800, 0);
void TimeZoneBinary::Reset() {
time_zone_binary_romfs = {};
time_zone_binary_mount_result = ResultUnknown;
time_zone_scratch_space.clear();
time_zone_scratch_space.resize(0x2800, 0);
}
Result TimeZoneReadBinary(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
std::string_view path) {
R_UNLESS(g_time_zone_binary_mount_result == ResultSuccess, g_time_zone_binary_mount_result);
Result TimeZoneBinary::Mount() {
Reset();
auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)};
auto& fsc{system.GetFileSystemController()};
std::unique_ptr<FileSys::NCA> nca{};
auto* bis_system = fsc.GetSystemNANDContents();
R_UNLESS(bis_system, ResultUnknown);
nca = bis_system->GetEntry(TimeZoneBinaryId, FileSys::ContentRecordType::Data);
if (nca) {
time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS());
}
if (time_zone_binary_romfs) {
// Validate that the romfs is readable, using invalid firmware keys can cause this to get
// set but the files to be garbage. In that case, we want to hit the next path and
// synthesise them instead.
time_zone_binary_mount_result = ResultSuccess;
Service::PSC::Time::LocationName name{"Etc/GMT"};
if (!IsValid(name)) {
Reset();
}
}
if (!time_zone_binary_romfs) {
time_zone_binary_romfs = FileSys::ExtractRomFS(
FileSys::SystemArchive::SynthesizeSystemArchive(TimeZoneBinaryId));
}
R_UNLESS(time_zone_binary_romfs, ResultUnknown);
time_zone_binary_mount_result = ResultSuccess;
R_SUCCEED();
}
Result TimeZoneBinary::Read(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
std::string_view path) {
R_UNLESS(time_zone_binary_mount_result == ResultSuccess, time_zone_binary_mount_result);
auto vfs_file{time_zone_binary_romfs->GetFileRelative(path)};
R_UNLESS(vfs_file, ResultUnknown);
auto file_size{vfs_file->GetSize()};
@ -36,82 +76,37 @@ Result TimeZoneReadBinary(size_t& out_read_size, std::span<u8> out_buffer, size_
R_SUCCEED();
}
} // namespace
void ResetTimeZoneBinary() {
g_time_zone_binary_romfs = {};
g_time_zone_binary_mount_result = ResultUnknown;
g_time_zone_scratch_space.clear();
g_time_zone_scratch_space.resize(0x2800, 0);
}
Result MountTimeZoneBinary(Core::System& system) {
ResetTimeZoneBinary();
auto& fsc{system.GetFileSystemController()};
std::unique_ptr<FileSys::NCA> nca{};
auto* bis_system = fsc.GetSystemNANDContents();
R_UNLESS(bis_system, ResultUnknown);
nca = bis_system->GetEntry(TimeZoneBinaryId, FileSys::ContentRecordType::Data);
if (nca) {
g_time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS());
}
if (g_time_zone_binary_romfs) {
// Validate that the romfs is readable, using invalid firmware keys can cause this to get
// set but the files to be garbage. In that case, we want to hit the next path and
// synthesise them instead.
g_time_zone_binary_mount_result = ResultSuccess;
Service::PSC::Time::LocationName name{"Etc/GMT"};
if (!IsTimeZoneBinaryValid(name)) {
ResetTimeZoneBinary();
}
}
if (!g_time_zone_binary_romfs) {
g_time_zone_binary_romfs = FileSys::ExtractRomFS(
FileSys::SystemArchive::SynthesizeSystemArchive(TimeZoneBinaryId));
}
R_UNLESS(g_time_zone_binary_romfs, ResultUnknown);
g_time_zone_binary_mount_result = ResultSuccess;
R_SUCCEED();
}
void GetTimeZoneBinaryListPath(std::string& out_path) {
if (g_time_zone_binary_mount_result != ResultSuccess) {
void TimeZoneBinary::GetListPath(std::string& out_path) {
if (time_zone_binary_mount_result != ResultSuccess) {
return;
}
// out_path = fmt::format("{}:/binaryList.txt", "TimeZoneBinary");
out_path = "/binaryList.txt";
}
void GetTimeZoneBinaryVersionPath(std::string& out_path) {
if (g_time_zone_binary_mount_result != ResultSuccess) {
void TimeZoneBinary::GetVersionPath(std::string& out_path) {
if (time_zone_binary_mount_result != ResultSuccess) {
return;
}
// out_path = fmt::format("{}:/version.txt", "TimeZoneBinary");
out_path = "/version.txt";
}
void GetTimeZoneZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name) {
if (g_time_zone_binary_mount_result != ResultSuccess) {
void TimeZoneBinary::GetTimeZonePath(std::string& out_path,
const Service::PSC::Time::LocationName& name) {
if (time_zone_binary_mount_result != ResultSuccess) {
return;
}
// out_path = fmt::format("{}:/zoneinfo/{}", "TimeZoneBinary", name);
out_path = fmt::format("/zoneinfo/{}", name.data());
}
bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name) {
bool TimeZoneBinary::IsValid(const Service::PSC::Time::LocationName& name) {
std::string path{};
GetTimeZoneZonePath(path, name);
GetTimeZonePath(path, name);
auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)};
auto vfs_file{time_zone_binary_romfs->GetFileRelative(path)};
if (!vfs_file) {
LOG_INFO(Service_Time, "Could not find timezone file {}", path);
return false;
@ -119,19 +114,19 @@ bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name) {
return vfs_file->GetSize() != 0;
}
u32 GetTimeZoneCount() {
u32 TimeZoneBinary::GetTimeZoneCount() {
std::string path{};
GetTimeZoneBinaryListPath(path);
GetListPath(path);
size_t bytes_read{};
if (TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space, 0x2800, path) != ResultSuccess) {
if (Read(bytes_read, time_zone_scratch_space, 0x2800, path) != ResultSuccess) {
return 0;
}
if (bytes_read == 0) {
return 0;
}
auto chars = std::span(reinterpret_cast<char*>(g_time_zone_scratch_space.data()), bytes_read);
auto chars = std::span(reinterpret_cast<char*>(time_zone_scratch_space.data()), bytes_read);
u32 count{};
for (auto chr : chars) {
if (chr == '\n') {
@ -141,50 +136,47 @@ u32 GetTimeZoneCount() {
return count;
}
Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version) {
Result TimeZoneBinary::GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version) {
std::string path{};
GetTimeZoneBinaryVersionPath(path);
GetVersionPath(path);
auto rule_version_buffer{std::span(reinterpret_cast<u8*>(&out_rule_version),
sizeof(Service::PSC::Time::RuleVersion))};
size_t bytes_read{};
R_TRY(TimeZoneReadBinary(bytes_read, rule_version_buffer, rule_version_buffer.size_bytes(),
path));
R_TRY(Read(bytes_read, rule_version_buffer, rule_version_buffer.size_bytes(), path));
rule_version_buffer[bytes_read] = 0;
R_SUCCEED();
}
Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
const Service::PSC::Time::LocationName& name) {
Result TimeZoneBinary::GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
const Service::PSC::Time::LocationName& name) {
std::string path{};
GetTimeZoneZonePath(path, name);
GetTimeZonePath(path, name);
size_t bytes_read{};
R_TRY(TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space,
g_time_zone_scratch_space.size(), path));
R_TRY(Read(bytes_read, time_zone_scratch_space, time_zone_scratch_space.size(), path));
out_rule = std::span(g_time_zone_scratch_space.data(), bytes_read);
out_rule = std::span(time_zone_scratch_space.data(), bytes_read);
out_rule_size = bytes_read;
R_SUCCEED();
}
Result GetTimeZoneLocationList(u32& out_count,
std::span<Service::PSC::Time::LocationName> out_names,
size_t max_names, u32 index) {
Result TimeZoneBinary::GetTimeZoneLocationList(
u32& out_count, std::span<Service::PSC::Time::LocationName> out_names, size_t max_names,
u32 index) {
std::string path{};
GetTimeZoneBinaryListPath(path);
GetListPath(path);
size_t bytes_read{};
R_TRY(TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space,
g_time_zone_scratch_space.size(), path));
R_TRY(Read(bytes_read, time_zone_scratch_space, time_zone_scratch_space.size(), path));
out_count = 0;
R_SUCCEED_IF(bytes_read == 0);
Service::PSC::Time::LocationName current_name{};
size_t current_name_len{};
std::span<const u8> chars{g_time_zone_scratch_space};
std::span<const u8> chars{time_zone_scratch_space};
u32 name_count{};
for (auto chr : chars) {

View file

@ -6,6 +6,7 @@
#include <span>
#include <string>
#include <string_view>
#include <vector>
#include "core/hle/service/psc/time/common.h"
@ -15,18 +16,34 @@ class System;
namespace Service::Glue::Time {
void ResetTimeZoneBinary();
Result MountTimeZoneBinary(Core::System& system);
void GetTimeZoneBinaryListPath(std::string& out_path);
void GetTimeZoneBinaryVersionPath(std::string& out_path);
void GetTimeZoneZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name);
bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name);
u32 GetTimeZoneCount();
Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version);
Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
const Service::PSC::Time::LocationName& name);
Result GetTimeZoneLocationList(u32& out_count,
std::span<Service::PSC::Time::LocationName> out_names,
size_t max_names, u32 index);
class TimeZoneBinary {
public:
explicit TimeZoneBinary(Core::System& system_)
: time_zone_scratch_space(0x2800, 0), system{system_} {}
Result Mount();
bool IsValid(const Service::PSC::Time::LocationName& name);
u32 GetTimeZoneCount();
Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version);
Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
const Service::PSC::Time::LocationName& name);
Result GetTimeZoneLocationList(u32& out_count,
std::span<Service::PSC::Time::LocationName> out_names,
size_t max_names, u32 index);
private:
void Reset();
Result Read(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
std::string_view path);
void GetListPath(std::string& out_path);
void GetVersionPath(std::string& out_path);
void GetTimeZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name);
FileSys::VirtualDir time_zone_binary_romfs{};
Result time_zone_binary_mount_result{ResultUnknown};
std::vector<u8> time_zone_scratch_space;
Core::System& system;
};
} // namespace Service::Glue::Time

View file

@ -16,23 +16,6 @@
#include "core/hle/service/sm/sm.h"
namespace Service::Glue::Time {
namespace {
bool g_ig_report_network_clock_context_set{};
Service::PSC::Time::SystemClockContext g_report_network_clock_context{};
bool g_ig_report_ephemeral_clock_context_set{};
Service::PSC::Time::SystemClockContext g_report_ephemeral_clock_context{};
template <typename T>
T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys,
const char* category, const char* name) {
T v{};
auto res = set_sys->GetSettingsItemValueImpl(v, category, name);
ASSERT(res == ResultSuccess);
return v;
}
} // namespace
TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource,
FileTimestampWorker& file_timestamp_worker)
@ -43,11 +26,6 @@ TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady
"Glue:TimeWorker:SteadyClockTimerEvent")},
m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")},
m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} {
g_ig_report_network_clock_context_set = false;
g_report_network_clock_context = {};
g_ig_report_ephemeral_clock_context_set = false;
g_report_ephemeral_clock_context = {};
m_timer_steady_clock_timing_event = Core::Timing::CreateEvent(
"Time::SteadyClockEvent",
[this](s64 time,
@ -82,6 +60,14 @@ TimeWorker::~TimeWorker() {
m_ctx.CloseEvent(m_timer_file_system);
}
template <typename T>
T TimeWorker::GetSettingsItemValue(const std::string& category, const std::string& name) {
T v{};
auto res = m_set_sys->GetSettingsItemValueImpl(v, category, name);
ASSERT(res == ResultSuccess);
return v;
}
void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> time_sm,
std::shared_ptr<Service::Set::ISystemSettingsServer> set_sys) {
m_set_sys = std::move(set_sys);
@ -91,8 +77,8 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t
m_alarm_worker.Initialize(m_time_m);
auto steady_clock_interval_m = GetSettingsItemValue<s32>(
m_set_sys, "time", "standard_steady_clock_rtc_update_interval_minutes");
auto steady_clock_interval_m =
GetSettingsItemValue<s32>("time", "standard_steady_clock_rtc_update_interval_minutes");
auto one_minute_ns{
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
std::chrono::nanoseconds(steady_clock_interval_ns),
m_timer_steady_clock_timing_event);
auto fs_notify_time_s =
GetSettingsItemValue<s32>(m_set_sys, "time", "notify_time_to_fs_interval_seconds");
auto fs_notify_time_s = GetSettingsItemValue<s32>("time", "notify_time_to_fs_interval_seconds");
auto one_second_ns{
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count()};
s64 fs_notify_time_ns{fs_notify_time_s * one_second_ns};
@ -218,14 +203,14 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
}
[[maybe_unused]] auto offset_before{
g_ig_report_network_clock_context_set ? g_report_network_clock_context.offset : 0};
m_ig_report_network_clock_context_set ? m_report_network_clock_context.offset : 0};
// TODO system report "standard_netclock_operation"
// "clock_time" = time
// "context_offset_before" = offset_before
// "context_offset_after" = context.offset
g_report_network_clock_context = context;
if (!g_ig_report_network_clock_context_set) {
g_ig_report_network_clock_context_set = true;
m_report_network_clock_context = context;
if (!m_ig_report_network_clock_context_set) {
m_ig_report_network_clock_context_set = true;
}
m_file_timestamp_worker.SetFilesystemPosixTime();
@ -247,16 +232,16 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
break;
}
[[maybe_unused]] auto offset_before{g_ig_report_ephemeral_clock_context_set
? g_report_ephemeral_clock_context.offset
[[maybe_unused]] auto offset_before{m_ig_report_ephemeral_clock_context_set
? m_report_ephemeral_clock_context.offset
: 0};
// TODO system report "ephemeral_netclock_operation"
// "clock_time" = time
// "context_offset_before" = offset_before
// "context_offset_after" = context.offset
g_report_ephemeral_clock_context = context;
if (!g_ig_report_ephemeral_clock_context_set) {
g_ig_report_ephemeral_clock_context_set = true;
m_report_ephemeral_clock_context = context;
if (!m_ig_report_ephemeral_clock_context_set) {
m_ig_report_ephemeral_clock_context_set = true;
}
break;
}

View file

@ -34,6 +34,9 @@ public:
void StartThread();
private:
template <typename T>
T GetSettingsItemValue(const std::string& category, const std::string& name);
void ThreadFunc(std::stop_token stop_token);
Core::System& m_system;
@ -59,6 +62,11 @@ private:
std::shared_ptr<Core::Timing::EventType> m_timer_file_system_timing_event;
AlarmWorker m_alarm_worker;
PmStateChangeHandler m_pm_state_change_handler;
bool m_ig_report_network_clock_context_set{};
Service::PSC::Time::SystemClockContext m_report_network_clock_context{};
bool m_ig_report_ephemeral_clock_context_set{};
Service::PSC::Time::SystemClockContext m_report_ephemeral_clock_context{};
};
} // namespace Service::Glue::Time

View file

@ -93,13 +93,19 @@ ServerManager::~ServerManager() {
m_threads.clear();
// Clean up ports.
for (auto it = m_servers.begin(); it != m_servers.end(); it = m_servers.erase(it)) {
delete std::addressof(*it);
auto port_it = m_servers.begin();
while (port_it != m_servers.end()) {
auto* const port = std::addressof(*port_it);
port_it = m_servers.erase(port_it);
delete port;
}
// Clean up sessions.
for (auto it = m_sessions.begin(); it != m_sessions.end(); it = m_sessions.erase(it)) {
delete std::addressof(*it);
auto session_it = m_sessions.begin();
while (session_it != m_sessions.end()) {
auto* const session = std::addressof(*session_it);
session_it = m_sessions.erase(session_it);
delete session;
}
// Close wakeup event.

View file

@ -36,22 +36,23 @@ std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) {
} // namespace
FileType IdentifyFile(FileSys::VirtualFile file) {
if (const auto romdir_type = IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) {
return *romdir_type;
} else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) {
return *nso_type;
if (const auto nsp_type = IdentifyFileLoader<AppLoader_NSP>(file)) {
return *nsp_type;
} else if (const auto xci_type = IdentifyFileLoader<AppLoader_XCI>(file)) {
return *xci_type;
} else if (const auto nro_type = IdentifyFileLoader<AppLoader_NRO>(file)) {
return *nro_type;
} else if (const auto nca_type = IdentifyFileLoader<AppLoader_NCA>(file)) {
return *nca_type;
} else if (const auto xci_type = IdentifyFileLoader<AppLoader_XCI>(file)) {
return *xci_type;
} else if (const auto nax_type = IdentifyFileLoader<AppLoader_NAX>(file)) {
return *nax_type;
} else if (const auto nsp_type = IdentifyFileLoader<AppLoader_NSP>(file)) {
return *nsp_type;
} else if (const auto kip_type = IdentifyFileLoader<AppLoader_KIP>(file)) {
return *kip_type;
} else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) {
return *nso_type;
} else if (const auto romdir_type =
IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) {
return *romdir_type;
} else {
return FileType::Unknown;
}

View file

@ -71,7 +71,7 @@ const char* GetType(GLenum type) {
void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar* message, const void* user_param) {
const char format[] = "{} {} {}: {}";
constexpr std::string_view format = "{} {} {}: {}";
const char* const str_source = GetSource(source);
const char* const str_type = GetType(type);

View file

@ -40,6 +40,12 @@ constexpr std::array DEPTH24_UNORM_STENCIL8_UINT{
VK_FORMAT_UNDEFINED,
};
constexpr std::array DEPTH24_UNORM_DONTCARE8{
VK_FORMAT_D32_SFLOAT,
VK_FORMAT_D16_UNORM,
VK_FORMAT_UNDEFINED,
};
constexpr std::array DEPTH16_UNORM_STENCIL8_UINT{
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D32_SFLOAT_S8_UINT,
@ -95,6 +101,8 @@ constexpr const VkFormat* GetFormatAlternatives(VkFormat format) {
return Alternatives::STENCIL8_UINT.data();
case VK_FORMAT_D24_UNORM_S8_UINT:
return Alternatives::DEPTH24_UNORM_STENCIL8_UINT.data();
case VK_FORMAT_X8_D24_UNORM_PACK32:
return Alternatives::DEPTH24_UNORM_DONTCARE8.data();
case VK_FORMAT_D16_UNORM_S8_UINT:
return Alternatives::DEPTH16_UNORM_STENCIL8_UINT.data();
case VK_FORMAT_B5G6R5_UNORM_PACK16: