early-access version 4101

This commit is contained in:
pineappleEA 2024-01-30 22:52:40 +01:00
parent 8b3524268f
commit f0e57883dd
23 changed files with 312 additions and 443 deletions

View file

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

View file

@ -5,7 +5,7 @@
#include "core/hle/service/caps/caps_a.h" #include "core/hle/service/caps/caps_a.h"
#include "core/hle/service/caps/caps_manager.h" #include "core/hle/service/caps/caps_manager.h"
#include "core/hle/service/caps/caps_result.h" #include "core/hle/service/caps/caps_result.h"
#include "core/hle/service/caps/caps_types.h" #include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
namespace Service::Capture { namespace Service::Capture {
@ -18,9 +18,9 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
{0, nullptr, "GetAlbumFileCount"}, {0, nullptr, "GetAlbumFileCount"},
{1, nullptr, "GetAlbumFileList"}, {1, nullptr, "GetAlbumFileList"},
{2, nullptr, "LoadAlbumFile"}, {2, nullptr, "LoadAlbumFile"},
{3, &IAlbumAccessorService::DeleteAlbumFile, "DeleteAlbumFile"}, {3, C<&IAlbumAccessorService::DeleteAlbumFile>, "DeleteAlbumFile"},
{4, nullptr, "StorageCopyAlbumFile"}, {4, nullptr, "StorageCopyAlbumFile"},
{5, &IAlbumAccessorService::IsAlbumMounted, "IsAlbumMounted"}, {5, C<&IAlbumAccessorService::IsAlbumMounted>, "IsAlbumMounted"},
{6, nullptr, "GetAlbumUsage"}, {6, nullptr, "GetAlbumUsage"},
{7, nullptr, "GetAlbumFileSize"}, {7, nullptr, "GetAlbumFileSize"},
{8, nullptr, "LoadAlbumFileThumbnail"}, {8, nullptr, "LoadAlbumFileThumbnail"},
@ -33,18 +33,18 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
{15, nullptr, "GetAlbumUsage3"}, {15, nullptr, "GetAlbumUsage3"},
{16, nullptr, "GetAlbumMountResult"}, {16, nullptr, "GetAlbumMountResult"},
{17, nullptr, "GetAlbumUsage16"}, {17, nullptr, "GetAlbumUsage16"},
{18, &IAlbumAccessorService::Unknown18, "Unknown18"}, {18, C<&IAlbumAccessorService::Unknown18>, "Unknown18"},
{19, nullptr, "Unknown19"}, {19, nullptr, "Unknown19"},
{100, nullptr, "GetAlbumFileCountEx0"}, {100, nullptr, "GetAlbumFileCountEx0"},
{101, &IAlbumAccessorService::GetAlbumFileListEx0, "GetAlbumFileListEx0"}, {101, C<&IAlbumAccessorService::GetAlbumFileListEx0>, "GetAlbumFileListEx0"},
{202, nullptr, "SaveEditedScreenShot"}, {202, nullptr, "SaveEditedScreenShot"},
{301, nullptr, "GetLastThumbnail"}, {301, nullptr, "GetLastThumbnail"},
{302, nullptr, "GetLastOverlayMovieThumbnail"}, {302, nullptr, "GetLastOverlayMovieThumbnail"},
{401, &IAlbumAccessorService::GetAutoSavingStorage, "GetAutoSavingStorage"}, {401, C<&IAlbumAccessorService::GetAutoSavingStorage>, "GetAutoSavingStorage"},
{501, nullptr, "GetRequiredStorageSpaceSizeToCopyAll"}, {501, nullptr, "GetRequiredStorageSpaceSizeToCopyAll"},
{1001, nullptr, "LoadAlbumScreenShotThumbnailImageEx0"}, {1001, nullptr, "LoadAlbumScreenShotThumbnailImageEx0"},
{1002, &IAlbumAccessorService::LoadAlbumScreenShotImageEx1, "LoadAlbumScreenShotImageEx1"}, {1002, C<&IAlbumAccessorService::LoadAlbumScreenShotImageEx1>, "LoadAlbumScreenShotImageEx1"},
{1003, &IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1, "LoadAlbumScreenShotThumbnailImageEx1"}, {1003, C<&IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1>, "LoadAlbumScreenShotThumbnailImageEx1"},
{8001, nullptr, "ForceAlbumUnmounted"}, {8001, nullptr, "ForceAlbumUnmounted"},
{8002, nullptr, "ResetAlbumMountStatus"}, {8002, nullptr, "ResetAlbumMountStatus"},
{8011, nullptr, "RefreshAlbumCache"}, {8011, nullptr, "RefreshAlbumCache"},
@ -62,138 +62,70 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
IAlbumAccessorService::~IAlbumAccessorService() = default; IAlbumAccessorService::~IAlbumAccessorService() = default;
void IAlbumAccessorService::DeleteAlbumFile(HLERequestContext& ctx) { Result IAlbumAccessorService::DeleteAlbumFile(AlbumFileId file_id) {
IPC::RequestParser rp{ctx};
const auto file_id{rp.PopRaw<AlbumFileId>()};
LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}", LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}",
file_id.application_id, file_id.storage, file_id.type); file_id.application_id, file_id.storage, file_id.type);
Result result = manager->DeleteAlbumFile(file_id); const Result result = manager->DeleteAlbumFile(file_id);
result = TranslateResult(result); R_RETURN(TranslateResult(result));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void IAlbumAccessorService::IsAlbumMounted(HLERequestContext& ctx) { Result IAlbumAccessorService::IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage) {
IPC::RequestParser rp{ctx};
const auto storage{rp.PopEnum<AlbumStorage>()};
LOG_INFO(Service_Capture, "called, storage={}", storage); LOG_INFO(Service_Capture, "called, storage={}", storage);
Result result = manager->IsAlbumMounted(storage); const Result result = manager->IsAlbumMounted(storage);
const bool is_mounted = result.IsSuccess(); *out_is_mounted = result.IsSuccess();
result = TranslateResult(result); R_RETURN(TranslateResult(result));
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(result);
rb.Push<u8>(is_mounted);
} }
void IAlbumAccessorService::Unknown18(HLERequestContext& ctx) { Result IAlbumAccessorService::Unknown18(
struct UnknownBuffer { Out<u32> out_buffer_size,
INSERT_PADDING_BYTES(0x10); OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_buffer) {
};
static_assert(sizeof(UnknownBuffer) == 0x10, "UnknownBuffer is an invalid size");
LOG_WARNING(Service_Capture, "(STUBBED) called"); LOG_WARNING(Service_Capture, "(STUBBED) called");
*out_buffer_size = 0;
std::vector<UnknownBuffer> buffer{}; R_SUCCEED();
if (!buffer.empty()) {
ctx.WriteBuffer(buffer);
}
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(static_cast<u32>(buffer.size()));
} }
void IAlbumAccessorService::GetAlbumFileListEx0(HLERequestContext& ctx) { Result IAlbumAccessorService::GetAlbumFileListEx0(
IPC::RequestParser rp{ctx}; Out<u64> out_entries_size, AlbumStorage storage, u8 flags,
const auto storage{rp.PopEnum<AlbumStorage>()}; OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
const auto flags{rp.Pop<u8>()};
const auto album_entry_size{ctx.GetWriteBufferNumElements<AlbumEntry>()};
LOG_INFO(Service_Capture, "called, storage={}, flags={}", storage, flags); LOG_INFO(Service_Capture, "called, storage={}, flags={}", storage, flags);
std::vector<AlbumEntry> entries; const Result result = manager->GetAlbumFileList(out_entries, *out_entries_size, storage, flags);
Result result = manager->GetAlbumFileList(entries, storage, flags); R_RETURN(TranslateResult(result));
result = TranslateResult(result);
entries.resize(std::min(album_entry_size, entries.size()));
if (!entries.empty()) {
ctx.WriteBuffer(entries);
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(result);
rb.Push<u64>(entries.size());
} }
void IAlbumAccessorService::GetAutoSavingStorage(HLERequestContext& ctx) { Result IAlbumAccessorService::GetAutoSavingStorage(Out<bool> out_is_autosaving) {
LOG_WARNING(Service_Capture, "(STUBBED) called"); LOG_WARNING(Service_Capture, "(STUBBED) called");
bool is_autosaving{}; const Result result = manager->GetAutoSavingStorage(*out_is_autosaving);
Result result = manager->GetAutoSavingStorage(is_autosaving); R_RETURN(TranslateResult(result));
result = TranslateResult(result);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(result);
rb.Push<u8>(is_autosaving);
} }
void IAlbumAccessorService::LoadAlbumScreenShotImageEx1(HLERequestContext& ctx) { Result IAlbumAccessorService::LoadAlbumScreenShotImageEx1(
IPC::RequestParser rp{ctx}; const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
const auto file_id{rp.PopRaw<AlbumFileId>()}; OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
const auto decoder_options{rp.PopRaw<ScreenShotDecodeOption>()}; OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
const auto image_buffer_size{ctx.GetWriteBufferSize(1)}; OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}", LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}",
file_id.application_id, file_id.storage, file_id.type, decoder_options.flags); file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
std::vector<u8> image; const Result result =
LoadAlbumScreenShotImageOutput image_output; manager->LoadAlbumScreenShotImage(*out_image_output, out_image, file_id, decoder_options);
Result result = R_RETURN(TranslateResult(result));
manager->LoadAlbumScreenShotImage(image_output, image, file_id, decoder_options);
result = TranslateResult(result);
if (image.size() > image_buffer_size) {
result = ResultWorkMemoryError;
}
if (result.IsSuccess()) {
ctx.WriteBuffer(image_output, 0);
ctx.WriteBuffer(image, 1);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
void IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1(HLERequestContext& ctx) { Result IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1(
IPC::RequestParser rp{ctx}; const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
const auto file_id{rp.PopRaw<AlbumFileId>()}; OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
const auto decoder_options{rp.PopRaw<ScreenShotDecodeOption>()}; OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}", LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}",
file_id.application_id, file_id.storage, file_id.type, decoder_options.flags); file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
std::vector<u8> image(ctx.GetWriteBufferSize(1)); const Result result = manager->LoadAlbumScreenShotThumbnail(*out_image_output, out_image,
LoadAlbumScreenShotImageOutput image_output; file_id, decoder_options);
Result result = R_RETURN(TranslateResult(result));
manager->LoadAlbumScreenShotThumbnail(image_output, image, file_id, decoder_options);
result = TranslateResult(result);
if (result.IsSuccess()) {
ctx.WriteBuffer(image_output, 0);
ctx.WriteBuffer(image, 1);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
} }
Result IAlbumAccessorService::TranslateResult(Result in_result) { Result IAlbumAccessorService::TranslateResult(Result in_result) {

View file

@ -3,6 +3,8 @@
#pragma once #pragma once
#include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core { namespace Core {
@ -19,13 +21,31 @@ public:
~IAlbumAccessorService() override; ~IAlbumAccessorService() override;
private: private:
void DeleteAlbumFile(HLERequestContext& ctx); Result DeleteAlbumFile(AlbumFileId file_id);
void IsAlbumMounted(HLERequestContext& ctx);
void Unknown18(HLERequestContext& ctx); Result IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage);
void GetAlbumFileListEx0(HLERequestContext& ctx);
void GetAutoSavingStorage(HLERequestContext& ctx); Result Unknown18(
void LoadAlbumScreenShotImageEx1(HLERequestContext& ctx); Out<u32> out_buffer_size,
void LoadAlbumScreenShotThumbnailImageEx1(HLERequestContext& ctx); OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure>
out_buffer);
Result GetAlbumFileListEx0(Out<u64> out_entries_size, AlbumStorage storage, u8 flags,
OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries);
Result GetAutoSavingStorage(Out<bool> out_is_autosaving);
Result LoadAlbumScreenShotImageEx1(
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
Result LoadAlbumScreenShotThumbnailImageEx1(
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
Result TranslateResult(Result in_result); Result TranslateResult(Result in_result);

View file

@ -6,6 +6,7 @@
#include "core/hle/service/caps/caps_manager.h" #include "core/hle/service/caps/caps_manager.h"
#include "core/hle/service/caps/caps_result.h" #include "core/hle/service/caps/caps_result.h"
#include "core/hle/service/caps/caps_types.h" #include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
namespace Service::Capture { namespace Service::Capture {
@ -17,7 +18,7 @@ IAlbumControlService::IAlbumControlService(Core::System& system_,
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{1, nullptr, "CaptureRawImage"}, {1, nullptr, "CaptureRawImage"},
{2, nullptr, "CaptureRawImageWithTimeout"}, {2, nullptr, "CaptureRawImageWithTimeout"},
{33, &IAlbumControlService::SetShimLibraryVersion, "SetShimLibraryVersion"}, {33, C<&IAlbumControlService::SetShimLibraryVersion>, "SetShimLibraryVersion"},
{1001, nullptr, "RequestTakingScreenShot"}, {1001, nullptr, "RequestTakingScreenShot"},
{1002, nullptr, "RequestTakingScreenShotWithTimeout"}, {1002, nullptr, "RequestTakingScreenShotWithTimeout"},
{1011, nullptr, "NotifyTakingScreenShotRefused"}, {1011, nullptr, "NotifyTakingScreenShotRefused"},
@ -42,16 +43,11 @@ IAlbumControlService::IAlbumControlService(Core::System& system_,
IAlbumControlService::~IAlbumControlService() = default; IAlbumControlService::~IAlbumControlService() = default;
void IAlbumControlService::SetShimLibraryVersion(HLERequestContext& ctx) { Result IAlbumControlService::SetShimLibraryVersion(ShimLibraryVersion library_version,
IPC::RequestParser rp{ctx}; ClientAppletResourceUserId aruid) {
const auto library_version{rp.Pop<u64>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
library_version, applet_resource_user_id); library_version, aruid.pid);
R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
} }
} // namespace Service::Capture } // namespace Service::Capture

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core { namespace Core {
@ -11,6 +12,7 @@ class System;
namespace Service::Capture { namespace Service::Capture {
class AlbumManager; class AlbumManager;
enum class ShimLibraryVersion : u64;
class IAlbumControlService final : public ServiceFramework<IAlbumControlService> { class IAlbumControlService final : public ServiceFramework<IAlbumControlService> {
public: public:
@ -19,7 +21,8 @@ public:
~IAlbumControlService() override; ~IAlbumControlService() override;
private: private:
void SetShimLibraryVersion(HLERequestContext& ctx); Result SetShimLibraryVersion(ShimLibraryVersion library_version,
ClientAppletResourceUserId aruid);
std::shared_ptr<AlbumManager> manager = nullptr; std::shared_ptr<AlbumManager> manager = nullptr;
}; };

View file

@ -58,8 +58,8 @@ Result AlbumManager::IsAlbumMounted(AlbumStorage storage) {
return is_mounted ? ResultSuccess : ResultIsNotMounted; return is_mounted ? ResultSuccess : ResultIsNotMounted;
} }
Result AlbumManager::GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage, Result AlbumManager::GetAlbumFileList(std::span<AlbumEntry> out_entries, u64& out_entries_count,
u8 flags) const { AlbumStorage storage, u8 flags) const {
if (storage > AlbumStorage::Sd) { if (storage > AlbumStorage::Sd) {
return ResultInvalidStorage; return ResultInvalidStorage;
} }
@ -72,51 +72,55 @@ Result AlbumManager::GetAlbumFileList(std::vector<AlbumEntry>& out_entries, Albu
if (file_id.storage != storage) { if (file_id.storage != storage) {
continue; continue;
} }
if (out_entries.size() >= SdAlbumFileLimit) { if (out_entries_count >= SdAlbumFileLimit) {
break;
}
if (out_entries_count >= out_entries.size()) {
break; break;
} }
const auto entry_size = Common::FS::GetSize(path); const auto entry_size = Common::FS::GetSize(path);
out_entries.push_back({ out_entries[out_entries_count++] = {
.entry_size = entry_size, .entry_size = entry_size,
.file_id = file_id, .file_id = file_id,
}); };
} }
return ResultSuccess; return ResultSuccess;
} }
Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries, Result AlbumManager::GetAlbumFileList(std::span<ApplicationAlbumFileEntry> out_entries,
ContentType content_type, s64 start_posix_time, u64& out_entries_count, ContentType content_type,
s64 end_posix_time, u64 aruid) const { s64 start_posix_time, s64 end_posix_time, u64 aruid) const {
if (!is_mounted) { if (!is_mounted) {
return ResultIsNotMounted; return ResultIsNotMounted;
} }
std::vector<ApplicationAlbumEntry> album_entries; std::vector<ApplicationAlbumEntry> album_entries(out_entries.size());
const auto start_date = ConvertToAlbumDateTime(start_posix_time); const auto start_date = ConvertToAlbumDateTime(start_posix_time);
const auto end_date = ConvertToAlbumDateTime(end_posix_time); const auto end_date = ConvertToAlbumDateTime(end_posix_time);
const auto result = GetAlbumFileList(album_entries, content_type, start_date, end_date, aruid); const auto result = GetAlbumFileList(album_entries, out_entries_count, content_type, start_date,
end_date, aruid);
if (result.IsError()) { if (result.IsError()) {
return result; return result;
} }
for (const auto& album_entry : album_entries) { for (std::size_t i = 0; i < out_entries_count; i++) {
ApplicationAlbumFileEntry entry{ out_entries[i] = {
.entry = album_entry, .entry = album_entries[i],
.datetime = album_entry.datetime, .datetime = album_entries[i].datetime,
.unknown = {}, .unknown = {},
}; };
out_entries.push_back(entry);
} }
return ResultSuccess; return ResultSuccess;
} }
Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries, Result AlbumManager::GetAlbumFileList(std::span<ApplicationAlbumEntry> out_entries,
ContentType content_type, AlbumFileDateTime start_date, u64& out_entries_count, ContentType content_type,
AlbumFileDateTime end_date, u64 aruid) const { AlbumFileDateTime start_date, AlbumFileDateTime end_date,
u64 aruid) const {
if (!is_mounted) { if (!is_mounted) {
return ResultIsNotMounted; return ResultIsNotMounted;
} }
@ -131,12 +135,15 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_en
if (file_id.date < end_date) { if (file_id.date < end_date) {
continue; continue;
} }
if (out_entries.size() >= SdAlbumFileLimit) { if (out_entries_count >= SdAlbumFileLimit) {
break;
}
if (out_entries_count >= out_entries.size()) {
break; break;
} }
const auto entry_size = Common::FS::GetSize(path); const auto entry_size = Common::FS::GetSize(path);
ApplicationAlbumEntry entry{ out_entries[out_entries_count++] = {
.size = entry_size, .size = entry_size,
.hash{}, .hash{},
.datetime = file_id.date, .datetime = file_id.date,
@ -144,7 +151,6 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_en
.content = content_type, .content = content_type,
.unknown = 1, .unknown = 1,
}; };
out_entries.push_back(entry);
} }
return ResultSuccess; return ResultSuccess;
@ -156,8 +162,7 @@ Result AlbumManager::GetAutoSavingStorage(bool& out_is_autosaving) const {
} }
Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output, Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output,
std::vector<u8>& out_image, std::span<u8> out_image, const AlbumFileId& file_id,
const AlbumFileId& file_id,
const ScreenShotDecodeOption& decoder_options) const { const ScreenShotDecodeOption& decoder_options) const {
if (file_id.storage > AlbumStorage::Sd) { if (file_id.storage > AlbumStorage::Sd) {
return ResultInvalidStorage; return ResultInvalidStorage;
@ -176,7 +181,9 @@ Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& ou
.orientation = AlbumImageOrientation::None, .orientation = AlbumImageOrientation::None,
.unknown_1{}, .unknown_1{},
.unknown_2{}, .unknown_2{},
.pad163{},
}, },
.pad179{},
}; };
std::filesystem::path path; std::filesystem::path path;
@ -186,14 +193,12 @@ Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& ou
return result; return result;
} }
out_image.resize(out_image_output.height * out_image_output.width * STBI_rgb_alpha);
return LoadImage(out_image, path, static_cast<int>(out_image_output.width), return LoadImage(out_image, path, static_cast<int>(out_image_output.width),
+static_cast<int>(out_image_output.height), decoder_options.flags); +static_cast<int>(out_image_output.height), decoder_options.flags);
} }
Result AlbumManager::LoadAlbumScreenShotThumbnail( Result AlbumManager::LoadAlbumScreenShotThumbnail(
LoadAlbumScreenShotImageOutput& out_image_output, std::vector<u8>& out_image, LoadAlbumScreenShotImageOutput& out_image_output, std::span<u8> out_image,
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options) const { const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options) const {
if (file_id.storage > AlbumStorage::Sd) { if (file_id.storage > AlbumStorage::Sd) {
return ResultInvalidStorage; return ResultInvalidStorage;
@ -212,7 +217,9 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(
.orientation = AlbumImageOrientation::None, .orientation = AlbumImageOrientation::None,
.unknown_1{}, .unknown_1{},
.unknown_2{}, .unknown_2{},
.pad163{},
}, },
.pad179{},
}; };
std::filesystem::path path; std::filesystem::path path;
@ -222,8 +229,6 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(
return result; return result;
} }
out_image.resize(out_image_output.height * out_image_output.width * STBI_rgb_alpha);
return LoadImage(out_image, path, static_cast<int>(out_image_output.width), return LoadImage(out_image, path, static_cast<int>(out_image_output.width),
+static_cast<int>(out_image_output.height), decoder_options.flags); +static_cast<int>(out_image_output.height), decoder_options.flags);
} }

View file

@ -42,20 +42,20 @@ public:
Result DeleteAlbumFile(const AlbumFileId& file_id); Result DeleteAlbumFile(const AlbumFileId& file_id);
Result IsAlbumMounted(AlbumStorage storage); Result IsAlbumMounted(AlbumStorage storage);
Result GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage, Result GetAlbumFileList(std::span<AlbumEntry> out_entries, u64& out_entries_count,
u8 flags) const; AlbumStorage storage, u8 flags) const;
Result GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries, Result GetAlbumFileList(std::span<ApplicationAlbumFileEntry> out_entries,
ContentType content_type, s64 start_posix_time, s64 end_posix_time, u64& out_entries_count, ContentType content_type, s64 start_posix_time,
u64 aruid) const; s64 end_posix_time, u64 aruid) const;
Result GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries, Result GetAlbumFileList(std::span<ApplicationAlbumEntry> out_entries, u64& out_entries_count,
ContentType content_type, AlbumFileDateTime start_date, ContentType content_type, AlbumFileDateTime start_date,
AlbumFileDateTime end_date, u64 aruid) const; AlbumFileDateTime end_date, u64 aruid) const;
Result GetAutoSavingStorage(bool& out_is_autosaving) const; Result GetAutoSavingStorage(bool& out_is_autosaving) const;
Result LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output, Result LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output,
std::vector<u8>& out_image, const AlbumFileId& file_id, std::span<u8> out_image, const AlbumFileId& file_id,
const ScreenShotDecodeOption& decoder_options) const; const ScreenShotDecodeOption& decoder_options) const;
Result LoadAlbumScreenShotThumbnail(LoadAlbumScreenShotImageOutput& out_image_output, Result LoadAlbumScreenShotThumbnail(LoadAlbumScreenShotImageOutput& out_image_output,
std::vector<u8>& out_image, const AlbumFileId& file_id, std::span<u8> out_image, const AlbumFileId& file_id,
const ScreenShotDecodeOption& decoder_options) const; const ScreenShotDecodeOption& decoder_options) const;
Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute, Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,

View file

@ -3,10 +3,9 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/hle/service/caps/caps_manager.h" #include "core/hle/service/caps/caps_manager.h"
#include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/caps/caps_ss.h" #include "core/hle/service/caps/caps_ss.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ipc_helpers.h"
namespace Service::Capture { namespace Service::Capture {
@ -17,9 +16,9 @@ IScreenShotService::IScreenShotService(Core::System& system_,
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{201, nullptr, "SaveScreenShot"}, {201, nullptr, "SaveScreenShot"},
{202, nullptr, "SaveEditedScreenShot"}, {202, nullptr, "SaveEditedScreenShot"},
{203, &IScreenShotService::SaveScreenShotEx0, "SaveScreenShotEx0"}, {203, C<&IScreenShotService::SaveScreenShotEx0>, "SaveScreenShotEx0"},
{204, nullptr, "SaveEditedScreenShotEx0"}, {204, nullptr, "SaveEditedScreenShotEx0"},
{206, &IScreenShotService::SaveEditedScreenShotEx1, "SaveEditedScreenShotEx1"}, {206, C<&IScreenShotService::SaveEditedScreenShotEx1>, "SaveEditedScreenShotEx1"},
{208, nullptr, "SaveScreenShotOfMovieEx1"}, {208, nullptr, "SaveScreenShotOfMovieEx1"},
{1000, nullptr, "Unknown1000"}, {1000, nullptr, "Unknown1000"},
}; };
@ -30,69 +29,38 @@ IScreenShotService::IScreenShotService(Core::System& system_,
IScreenShotService::~IScreenShotService() = default; IScreenShotService::~IScreenShotService() = default;
void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) { Result IScreenShotService::SaveScreenShotEx0(
IPC::RequestParser rp{ctx}; Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
struct Parameters { AlbumReportOption report_option, ClientAppletResourceUserId aruid,
ScreenShotAttribute attribute{}; InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
AlbumReportOption report_option{}; image_data_buffer) {
INSERT_PADDING_BYTES(0x4);
u64 applet_resource_user_id{};
};
static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
const auto image_data_buffer = ctx.ReadBuffer();
LOG_INFO(Service_Capture, LOG_INFO(Service_Capture,
"called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}", "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}",
parameters.report_option, image_data_buffer.size(), report_option, image_data_buffer.size(), aruid.pid);
parameters.applet_resource_user_id);
ApplicationAlbumEntry entry{};
manager->FlipVerticallyOnWrite(false); manager->FlipVerticallyOnWrite(false);
const auto result = R_RETURN(manager->SaveScreenShot(*out_entry, attribute, report_option, image_data_buffer,
manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, aruid.pid));
image_data_buffer, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(result);
rb.PushRaw(entry);
} }
void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) { Result IScreenShotService::SaveEditedScreenShotEx1(
IPC::RequestParser rp{ctx}; Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute, u64 width,
struct Parameters { u64 height, u64 thumbnail_width, u64 thumbnail_height, const AlbumFileId& file_id,
ScreenShotAttribute attribute; const InLargeData<std::array<u8, 0x400>, BufferAttr_HipcMapAlias> application_data_buffer,
u64 width; const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
u64 height; image_data_buffer,
u64 thumbnail_width; const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
u64 thumbnail_height; thumbnail_image_data_buffer) {
AlbumFileId file_id;
};
static_assert(sizeof(Parameters) == 0x78, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
const auto application_data_buffer = ctx.ReadBuffer(0);
const auto image_data_buffer = ctx.ReadBuffer(1);
const auto thumbnail_image_data_buffer = ctx.ReadBuffer(2);
LOG_INFO(Service_Capture, LOG_INFO(Service_Capture,
"called, width={}, height={}, thumbnail_width={}, thumbnail_height={}, " "called, width={}, height={}, thumbnail_width={}, thumbnail_height={}, "
"application_id={:016x}, storage={}, type={}, app_data_buffer_size={}, " "application_id={:016x}, storage={}, type={}, "
"image_data_buffer_size={}, thumbnail_image_buffer_size={}", "image_data_buffer_size={}, thumbnail_image_buffer_size={}",
parameters.width, parameters.height, parameters.thumbnail_width, width, height, thumbnail_width, thumbnail_height, file_id.application_id,
parameters.thumbnail_height, parameters.file_id.application_id, file_id.storage, file_id.type, image_data_buffer.size(),
parameters.file_id.storage, parameters.file_id.type, application_data_buffer.size(), thumbnail_image_data_buffer.size());
image_data_buffer.size(), thumbnail_image_data_buffer.size());
ApplicationAlbumEntry entry{};
manager->FlipVerticallyOnWrite(false); manager->FlipVerticallyOnWrite(false);
const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute, R_RETURN(manager->SaveEditedScreenShot(*out_entry, attribute, file_id, image_data_buffer));
parameters.file_id, image_data_buffer);
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(result);
rb.PushRaw(entry);
} }
} // namespace Service::Capture } // namespace Service::Capture

View file

@ -3,6 +3,8 @@
#pragma once #pragma once
#include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core { namespace Core {
@ -17,8 +19,20 @@ public:
~IScreenShotService() override; ~IScreenShotService() override;
private: private:
void SaveScreenShotEx0(HLERequestContext& ctx); Result SaveScreenShotEx0(
void SaveEditedScreenShotEx1(HLERequestContext& ctx); Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
AlbumReportOption report_option, ClientAppletResourceUserId aruid,
InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
image_data_buffer);
Result SaveEditedScreenShotEx1(
Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute, u64 width,
u64 height, u64 thumbnail_width, u64 thumbnail_height, const AlbumFileId& file_id,
const InLargeData<std::array<u8, 0x400>, BufferAttr_HipcMapAlias> application_data_buffer,
const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
image_data_buffer,
const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
thumbnail_image_data_buffer);
std::shared_ptr<AlbumManager> manager; std::shared_ptr<AlbumManager> manager;
}; };

View file

@ -6,6 +6,7 @@
#include "core/hle/service/caps/caps_manager.h" #include "core/hle/service/caps/caps_manager.h"
#include "core/hle/service/caps/caps_su.h" #include "core/hle/service/caps/caps_su.h"
#include "core/hle/service/caps/caps_types.h" #include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
#include "video_core/renderer_base.h" #include "video_core/renderer_base.h"
@ -16,10 +17,10 @@ IScreenShotApplicationService::IScreenShotApplicationService(
: ServiceFramework{system_, "caps:su"}, manager{album_manager} { : ServiceFramework{system_, "caps:su"}, manager{album_manager} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{32, &IScreenShotApplicationService::SetShimLibraryVersion, "SetShimLibraryVersion"}, {32, C<&IScreenShotApplicationService::SetShimLibraryVersion>, "SetShimLibraryVersion"},
{201, nullptr, "SaveScreenShot"}, {201, nullptr, "SaveScreenShot"},
{203, &IScreenShotApplicationService::SaveScreenShotEx0, "SaveScreenShotEx0"}, {203, C<&IScreenShotApplicationService::SaveScreenShotEx0>, "SaveScreenShotEx0"},
{205, &IScreenShotApplicationService::SaveScreenShotEx1, "SaveScreenShotEx1"}, {205, C<&IScreenShotApplicationService::SaveScreenShotEx1>, "SaveScreenShotEx1"},
{210, nullptr, "SaveScreenShotEx2"}, {210, nullptr, "SaveScreenShotEx2"},
}; };
// clang-format on // clang-format on
@ -29,77 +30,40 @@ IScreenShotApplicationService::IScreenShotApplicationService(
IScreenShotApplicationService::~IScreenShotApplicationService() = default; IScreenShotApplicationService::~IScreenShotApplicationService() = default;
void IScreenShotApplicationService::SetShimLibraryVersion(HLERequestContext& ctx) { Result IScreenShotApplicationService::SetShimLibraryVersion(ShimLibraryVersion library_version,
IPC::RequestParser rp{ctx}; ClientAppletResourceUserId aruid) {
const auto library_version{rp.Pop<u64>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
library_version, applet_resource_user_id); library_version, aruid.pid);
R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
} }
void IScreenShotApplicationService::SaveScreenShotEx0(HLERequestContext& ctx) { Result IScreenShotApplicationService::SaveScreenShotEx0(
IPC::RequestParser rp{ctx}; Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
struct Parameters { AlbumReportOption report_option, ClientAppletResourceUserId aruid,
ScreenShotAttribute attribute{}; InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
AlbumReportOption report_option{}; image_data_buffer) {
INSERT_PADDING_BYTES(0x4);
u64 applet_resource_user_id{};
};
static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
const auto image_data_buffer = ctx.ReadBuffer();
LOG_INFO(Service_Capture, LOG_INFO(Service_Capture,
"called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}", "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}",
parameters.report_option, image_data_buffer.size(), report_option, image_data_buffer.size(), aruid.pid);
parameters.applet_resource_user_id);
ApplicationAlbumEntry entry{};
manager->FlipVerticallyOnWrite(false); manager->FlipVerticallyOnWrite(false);
const auto result = R_RETURN(manager->SaveScreenShot(*out_entry, attribute, report_option, image_data_buffer,
manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, aruid.pid));
image_data_buffer, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(result);
rb.PushRaw(entry);
} }
void IScreenShotApplicationService::SaveScreenShotEx1(HLERequestContext& ctx) { Result IScreenShotApplicationService::SaveScreenShotEx1(
IPC::RequestParser rp{ctx}; Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
struct Parameters { AlbumReportOption report_option, ClientAppletResourceUserId aruid,
ScreenShotAttribute attribute{}; const InLargeData<ApplicationData, BufferAttr_HipcMapAlias> app_data_buffer,
AlbumReportOption report_option{}; const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
INSERT_PADDING_BYTES(0x4); image_data_buffer) {
u64 applet_resource_user_id{};
};
static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
const auto app_data_buffer = ctx.ReadBuffer(0);
const auto image_data_buffer = ctx.ReadBuffer(1);
LOG_INFO(Service_Capture, LOG_INFO(Service_Capture,
"called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}", "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}",
parameters.report_option, image_data_buffer.size(), report_option, image_data_buffer.size(), aruid.pid);
parameters.applet_resource_user_id);
ApplicationAlbumEntry entry{};
ApplicationData app_data{};
std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData));
manager->FlipVerticallyOnWrite(false); manager->FlipVerticallyOnWrite(false);
const auto result = R_RETURN(manager->SaveScreenShot(*out_entry, attribute, report_option, *app_data_buffer,
manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, app_data, image_data_buffer, aruid.pid));
image_data_buffer, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(result);
rb.PushRaw(entry);
} }
void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption report_option) { void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption report_option) {
@ -112,6 +76,7 @@ void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption r
.orientation = Capture::AlbumImageOrientation::None, .orientation = Capture::AlbumImageOrientation::None,
.unknown_1{}, .unknown_1{},
.unknown_2{}, .unknown_2{},
.pad163{},
}; };
renderer.RequestScreenshot( renderer.RequestScreenshot(

View file

@ -3,6 +3,8 @@
#pragma once #pragma once
#include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core { namespace Core {
@ -26,9 +28,19 @@ private:
static constexpr std::size_t screenshot_height = 720; static constexpr std::size_t screenshot_height = 720;
static constexpr std::size_t bytes_per_pixel = 4; static constexpr std::size_t bytes_per_pixel = 4;
void SetShimLibraryVersion(HLERequestContext& ctx); Result SetShimLibraryVersion(ShimLibraryVersion library_version,
void SaveScreenShotEx0(HLERequestContext& ctx); ClientAppletResourceUserId aruid);
void SaveScreenShotEx1(HLERequestContext& ctx); Result SaveScreenShotEx0(
Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
AlbumReportOption report_option, ClientAppletResourceUserId aruid,
InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
image_data_buffer);
Result SaveScreenShotEx1(
Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
AlbumReportOption report_option, ClientAppletResourceUserId aruid,
const InLargeData<ApplicationData, BufferAttr_HipcMapAlias> app_data_buffer,
const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
image_data_buffer);
std::array<u8, screenshot_width * screenshot_height * bytes_per_pixel> image_data; std::array<u8, screenshot_width * screenshot_height * bytes_per_pixel> image_data;

View file

@ -41,6 +41,10 @@ enum class ScreenShotDecoderFlag : u64 {
EnableBlockSmoothing = 1 << 1, EnableBlockSmoothing = 1 << 1,
}; };
enum class ShimLibraryVersion : u64 {
Version1 = 1,
};
// This is nn::capsrv::AlbumFileDateTime // This is nn::capsrv::AlbumFileDateTime
struct AlbumFileDateTime { struct AlbumFileDateTime {
s16 year{}; s16 year{};
@ -144,19 +148,23 @@ static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30,
"ApplicationAlbumFileEntry has incorrect size."); "ApplicationAlbumFileEntry has incorrect size.");
struct ApplicationData { struct ApplicationData {
std::array<u8, 0x400> data{}; std::array<u8, 0x400> data;
u32 data_size{}; u32 data_size;
}; };
static_assert(sizeof(ApplicationData) == 0x404, "ApplicationData is an invalid size"); static_assert(sizeof(ApplicationData) == 0x404, "ApplicationData is an invalid size");
static_assert(std::is_trivial_v<ApplicationData>,
"ApplicationData type must be trivially copyable.");
struct ScreenShotAttribute { struct ScreenShotAttribute {
u32 unknown_0{}; u32 unknown_0;
AlbumImageOrientation orientation{}; AlbumImageOrientation orientation;
u32 unknown_1{}; u32 unknown_1;
u32 unknown_2{}; u32 unknown_2;
INSERT_PADDING_BYTES(0x30); INSERT_PADDING_BYTES_NOINIT(0x30);
}; };
static_assert(sizeof(ScreenShotAttribute) == 0x40, "ScreenShotAttribute is an invalid size"); static_assert(sizeof(ScreenShotAttribute) == 0x40, "ScreenShotAttribute is an invalid size");
static_assert(std::is_trivial_v<ScreenShotAttribute>,
"ScreenShotAttribute type must be trivially copyable.");
struct ScreenShotDecodeOption { struct ScreenShotDecodeOption {
ScreenShotDecoderFlag flags{}; ScreenShotDecoderFlag flags{};
@ -165,13 +173,15 @@ struct ScreenShotDecodeOption {
static_assert(sizeof(ScreenShotDecodeOption) == 0x20, "ScreenShotDecodeOption is an invalid size"); static_assert(sizeof(ScreenShotDecodeOption) == 0x20, "ScreenShotDecodeOption is an invalid size");
struct LoadAlbumScreenShotImageOutput { struct LoadAlbumScreenShotImageOutput {
s64 width{}; s64 width;
s64 height{}; s64 height;
ScreenShotAttribute attribute{}; ScreenShotAttribute attribute;
INSERT_PADDING_BYTES(0x400); INSERT_PADDING_BYTES_NOINIT(0x400);
}; };
static_assert(sizeof(LoadAlbumScreenShotImageOutput) == 0x450, static_assert(sizeof(LoadAlbumScreenShotImageOutput) == 0x450,
"LoadAlbumScreenShotImageOutput is an invalid size"); "LoadAlbumScreenShotImageOutput is an invalid size");
static_assert(std::is_trivial_v<LoadAlbumScreenShotImageOutput>,
"LoadAlbumScreenShotImageOutput type must be trivially copyable.");
struct LoadAlbumScreenShotImageOutputForApplication { struct LoadAlbumScreenShotImageOutputForApplication {
s64 width{}; s64 width{};

View file

@ -5,6 +5,7 @@
#include "core/hle/service/caps/caps_manager.h" #include "core/hle/service/caps/caps_manager.h"
#include "core/hle/service/caps/caps_types.h" #include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/caps/caps_u.h" #include "core/hle/service/caps/caps_u.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
namespace Service::Capture { namespace Service::Capture {
@ -14,8 +15,8 @@ IAlbumApplicationService::IAlbumApplicationService(Core::System& system_,
: ServiceFramework{system_, "caps:u"}, manager{album_manager} { : ServiceFramework{system_, "caps:u"}, manager{album_manager} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{32, &IAlbumApplicationService::SetShimLibraryVersion, "SetShimLibraryVersion"}, {32, C<&IAlbumApplicationService::SetShimLibraryVersion>, "SetShimLibraryVersion"},
{102, &IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated, "GetAlbumFileList0AafeAruidDeprecated"}, {102, C<&IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated>, "GetAlbumFileList0AafeAruidDeprecated"},
{103, nullptr, "DeleteAlbumFileByAruid"}, {103, nullptr, "DeleteAlbumFileByAruid"},
{104, nullptr, "GetAlbumFileSizeByAruid"}, {104, nullptr, "GetAlbumFileSizeByAruid"},
{105, nullptr, "DeleteAlbumFileByAruidForDebug"}, {105, nullptr, "DeleteAlbumFileByAruidForDebug"},
@ -24,7 +25,7 @@ IAlbumApplicationService::IAlbumApplicationService(Core::System& system_,
{130, nullptr, "PrecheckToCreateContentsByAruid"}, {130, nullptr, "PrecheckToCreateContentsByAruid"},
{140, nullptr, "GetAlbumFileList1AafeAruidDeprecated"}, {140, nullptr, "GetAlbumFileList1AafeAruidDeprecated"},
{141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"}, {141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"},
{142, &IAlbumApplicationService::GetAlbumFileList3AaeAruid, "GetAlbumFileList3AaeAruid"}, {142, C<&IAlbumApplicationService::GetAlbumFileList3AaeAruid>, "GetAlbumFileList3AaeAruid"},
{143, nullptr, "GetAlbumFileList4AaeUidAruid"}, {143, nullptr, "GetAlbumFileList4AaeUidAruid"},
{144, nullptr, "GetAllAlbumFileList3AaeAruid"}, {144, nullptr, "GetAllAlbumFileList3AaeAruid"},
{60002, nullptr, "OpenAccessorSessionForApplication"}, {60002, nullptr, "OpenAccessorSessionForApplication"},
@ -36,101 +37,40 @@ IAlbumApplicationService::IAlbumApplicationService(Core::System& system_,
IAlbumApplicationService::~IAlbumApplicationService() = default; IAlbumApplicationService::~IAlbumApplicationService() = default;
void IAlbumApplicationService::SetShimLibraryVersion(HLERequestContext& ctx) { Result IAlbumApplicationService::SetShimLibraryVersion(ShimLibraryVersion library_version,
IPC::RequestParser rp{ctx}; ClientAppletResourceUserId aruid) {
const auto library_version{rp.Pop<u64>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
library_version, applet_resource_user_id); library_version, aruid.pid);
R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
} }
void IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(HLERequestContext& ctx) { Result IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(
IPC::RequestParser rp{ctx}; Out<u64> out_entries_count, ContentType content_type, s64 start_posix_time, s64 end_posix_time,
struct Parameters { ClientAppletResourceUserId aruid,
ContentType content_type; OutArray<ApplicationAlbumFileEntry, BufferAttr_HipcMapAlias> out_entries) {
INSERT_PADDING_BYTES(7);
s64 start_posix_time;
s64 end_posix_time;
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_Capture, LOG_WARNING(Service_Capture,
"(STUBBED) called. content_type={}, start_posix_time={}, end_posix_time={}, " "(STUBBED) called. content_type={}, start_posix_time={}, end_posix_time={}, "
"applet_resource_user_id={}", "applet_resource_user_id={}",
parameters.content_type, parameters.start_posix_time, parameters.end_posix_time, content_type, start_posix_time, end_posix_time, aruid.pid);
parameters.applet_resource_user_id);
Result result = ResultSuccess; R_TRY(manager->IsAlbumMounted(AlbumStorage::Sd));
R_RETURN(manager->GetAlbumFileList(out_entries, *out_entries_count, content_type,
if (result.IsSuccess()) { start_posix_time, end_posix_time, aruid.pid));
result = manager->IsAlbumMounted(AlbumStorage::Sd);
}
std::vector<ApplicationAlbumFileEntry> entries;
if (result.IsSuccess()) {
result = manager->GetAlbumFileList(entries, parameters.content_type,
parameters.start_posix_time, parameters.end_posix_time,
parameters.applet_resource_user_id);
}
if (!entries.empty()) {
ctx.WriteBuffer(entries);
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(result);
rb.Push<u64>(entries.size());
} }
void IAlbumApplicationService::GetAlbumFileList3AaeAruid(HLERequestContext& ctx) { Result IAlbumApplicationService::GetAlbumFileList3AaeAruid(
IPC::RequestParser rp{ctx}; Out<u64> out_entries_count, ContentType content_type, AlbumFileDateTime start_date_time,
struct Parameters { AlbumFileDateTime end_date_time, ClientAppletResourceUserId aruid,
ContentType content_type; OutArray<ApplicationAlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
INSERT_PADDING_BYTES(1);
AlbumFileDateTime start_date_time;
AlbumFileDateTime end_date_time;
INSERT_PADDING_BYTES(6);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_Capture, LOG_WARNING(Service_Capture,
"(STUBBED) called. content_type={}, start_date={}/{}/{}, " "(STUBBED) called. content_type={}, start_date={}/{}/{}, "
"end_date={}/{}/{}, applet_resource_user_id={}", "end_date={}/{}/{}, applet_resource_user_id={}",
parameters.content_type, parameters.start_date_time.year, content_type, start_date_time.year, start_date_time.month, start_date_time.day,
parameters.start_date_time.month, parameters.start_date_time.day, end_date_time.year, end_date_time.month, end_date_time.day, aruid.pid);
parameters.end_date_time.year, parameters.end_date_time.month,
parameters.end_date_time.day, parameters.applet_resource_user_id);
Result result = ResultSuccess; R_TRY(manager->IsAlbumMounted(AlbumStorage::Sd));
R_RETURN(manager->GetAlbumFileList(out_entries, *out_entries_count, content_type,
if (result.IsSuccess()) { start_date_time, end_date_time, aruid.pid));
result = manager->IsAlbumMounted(AlbumStorage::Sd);
}
std::vector<ApplicationAlbumEntry> entries;
if (result.IsSuccess()) {
result =
manager->GetAlbumFileList(entries, parameters.content_type, parameters.start_date_time,
parameters.end_date_time, parameters.applet_resource_user_id);
}
if (!entries.empty()) {
ctx.WriteBuffer(entries);
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(result);
rb.Push<u64>(entries.size());
} }
} // namespace Service::Capture } // namespace Service::Capture

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core { namespace Core {
@ -19,9 +20,18 @@ public:
~IAlbumApplicationService() override; ~IAlbumApplicationService() override;
private: private:
void SetShimLibraryVersion(HLERequestContext& ctx); Result SetShimLibraryVersion(ShimLibraryVersion library_version,
void GetAlbumFileList0AafeAruidDeprecated(HLERequestContext& ctx); ClientAppletResourceUserId aruid);
void GetAlbumFileList3AaeAruid(HLERequestContext& ctx);
Result GetAlbumFileList0AafeAruidDeprecated(
Out<u64> out_entries_count, ContentType content_type, s64 start_posix_time,
s64 end_posix_time, ClientAppletResourceUserId aruid,
OutArray<ApplicationAlbumFileEntry, BufferAttr_HipcMapAlias> out_entries);
Result GetAlbumFileList3AaeAruid(
Out<u64> out_entries_count, ContentType content_type, AlbumFileDateTime start_date_time,
AlbumFileDateTime end_date_time, ClientAppletResourceUserId aruid,
OutArray<ApplicationAlbumEntry, BufferAttr_HipcMapAlias> out_entries);
std::shared_ptr<AlbumManager> manager = nullptr; std::shared_ptr<AlbumManager> manager = nullptr;
}; };

View file

@ -283,7 +283,7 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex + 1, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp); return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex + 1, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InLargeData) { } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InLargeData) {
constexpr size_t BufferSize = sizeof(ArgType); constexpr size_t BufferSize = sizeof(typename ArgType::Type);
// Clear the existing data. // Clear the existing data.
std::memset(&std::get<ArgIndex>(args), 0, BufferSize); std::memset(&std::get<ArgIndex>(args), 0, BufferSize);
@ -324,7 +324,7 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp); return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) { } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
constexpr size_t BufferSize = sizeof(ArgType); constexpr size_t BufferSize = sizeof(typename ArgType::Type);
// Clear the existing data. // Clear the existing data.
std::memset(&std::get<ArgIndex>(args).raw, 0, BufferSize); std::memset(&std::get<ArgIndex>(args).raw, 0, BufferSize);
@ -394,7 +394,7 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp); return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) { } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
constexpr size_t BufferSize = sizeof(ArgType); constexpr size_t BufferSize = sizeof(typename ArgType::Type);
ASSERT(ctx.CanWriteBuffer(OutBufferIndex)); ASSERT(ctx.CanWriteBuffer(OutBufferIndex));
if constexpr (ArgType::Attr & BufferAttr_HipcAutoSelect) { if constexpr (ArgType::Attr & BufferAttr_HipcAutoSelect) {

View file

@ -127,15 +127,7 @@ TimeManager::TimeManager(Core::System& system)
res = m_set_sys->GetUserSystemClockContext(user_clock_context); res = m_set_sys->GetUserSystemClockContext(user_clock_context);
ASSERT(res == ResultSuccess); ASSERT(res == ResultSuccess);
// TODO the local clock should initialise with this epoch time, and be updated somewhere else on
// first boot to update it, but I haven't been able to find that point (likely via ntc's auto
// correct as it's defaulted to be enabled). So to get a time that isn't stuck in the past for
// first boot, grab the current real seconds.
auto epoch_time{GetEpochTimeFromInitialYear(m_set_sys)}; auto epoch_time{GetEpochTimeFromInitialYear(m_set_sys)};
if (user_clock_context == Service::PSC::Time::SystemClockContext{}) {
m_steady_clock_resource.GetRtcTimeInSeconds(epoch_time);
}
res = m_time_m->SetupStandardLocalSystemClockCore(user_clock_context, epoch_time); res = m_time_m->SetupStandardLocalSystemClockCore(user_clock_context, epoch_time);
ASSERT(res == ResultSuccess); ASSERT(res == ResultSuccess);

View file

@ -8,6 +8,7 @@
#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/hid/hid_server.h" #include "core/hle/service/hid/hid_server.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
#include "core/memory.h" #include "core/memory.h"
@ -153,7 +154,7 @@ IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> r
{104, &IHidServer::DeactivateNpad, "DeactivateNpad"}, {104, &IHidServer::DeactivateNpad, "DeactivateNpad"},
{106, &IHidServer::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"}, {106, &IHidServer::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
{107, &IHidServer::DisconnectNpad, "DisconnectNpad"}, {107, &IHidServer::DisconnectNpad, "DisconnectNpad"},
{108, &IHidServer::GetPlayerLedPattern, "GetPlayerLedPattern"}, {108, C<&IHidServer::GetPlayerLedPattern>, "GetPlayerLedPattern"},
{109, &IHidServer::ActivateNpadWithRevision, "ActivateNpadWithRevision"}, {109, &IHidServer::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
{120, &IHidServer::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, {120, &IHidServer::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
{121, &IHidServer::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, {121, &IHidServer::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
@ -1135,19 +1136,39 @@ void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) { Result IHidServer::GetPlayerLedPattern(Out<Core::HID::LedPattern> out_led_pattern,
IPC::RequestParser rp{ctx}; Core::HID::NpadIdType npad_id) {
const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
Core::HID::LedPattern pattern{0, 0, 0, 0};
auto controller = GetResourceManager()->GetNpad();
const auto result = controller->GetLedPattern(npad_id, pattern);
LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id); LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
IPC::ResponseBuilder rb{ctx, 4}; switch (npad_id) {
rb.Push(result); case Core::HID::NpadIdType::Player1:
rb.Push(pattern.raw); *out_led_pattern = Core::HID::LedPattern{1, 0, 0, 0};
R_SUCCEED();
case Core::HID::NpadIdType::Player2:
*out_led_pattern = Core::HID::LedPattern{1, 1, 0, 0};
R_SUCCEED();
case Core::HID::NpadIdType::Player3:
*out_led_pattern = Core::HID::LedPattern{1, 1, 1, 0};
R_SUCCEED();
case Core::HID::NpadIdType::Player4:
*out_led_pattern = Core::HID::LedPattern{1, 1, 1, 1};
R_SUCCEED();
case Core::HID::NpadIdType::Player5:
*out_led_pattern = Core::HID::LedPattern{1, 0, 0, 1};
R_SUCCEED();
case Core::HID::NpadIdType::Player6:
*out_led_pattern = Core::HID::LedPattern{1, 0, 1, 0};
R_SUCCEED();
case Core::HID::NpadIdType::Player7:
*out_led_pattern = Core::HID::LedPattern{1, 0, 1, 1};
R_SUCCEED();
case Core::HID::NpadIdType::Player8:
*out_led_pattern = Core::HID::LedPattern{0, 1, 1, 0};
R_SUCCEED();
default:
*out_led_pattern = Core::HID::LedPattern{0, 0, 0, 0};
R_SUCCEED();
}
} }
void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {

View file

@ -3,7 +3,9 @@
#pragma once #pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "hid_core/hid_types.h"
namespace Core { namespace Core {
class System; class System;
@ -66,7 +68,8 @@ private:
void DeactivateNpad(HLERequestContext& ctx); void DeactivateNpad(HLERequestContext& ctx);
void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx); void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
void DisconnectNpad(HLERequestContext& ctx); void DisconnectNpad(HLERequestContext& ctx);
void GetPlayerLedPattern(HLERequestContext& ctx); Result GetPlayerLedPattern(Out<Core::HID::LedPattern> out_led_pattern,
Core::HID::NpadIdType npad_id);
void ActivateNpadWithRevision(HLERequestContext& ctx); void ActivateNpadWithRevision(HLERequestContext& ctx);
void SetNpadJoyHoldType(HLERequestContext& ctx); void SetNpadJoyHoldType(HLERequestContext& ctx);
void GetNpadJoyHoldType(HLERequestContext& ctx); void GetNpadJoyHoldType(HLERequestContext& ctx);

View file

@ -227,8 +227,7 @@ template <>
struct fmt::formatter<Service::PSC::Time::LocationName> : fmt::formatter<fmt::string_view> { struct fmt::formatter<Service::PSC::Time::LocationName> : fmt::formatter<fmt::string_view> {
template <typename FormatContext> template <typename FormatContext>
auto format(const Service::PSC::Time::LocationName& name, FormatContext& ctx) const { auto format(const Service::PSC::Time::LocationName& name, FormatContext& ctx) const {
std::string_view n{name.data(), name.size()}; return formatter<string_view>::format(name.data(), ctx);
return formatter<string_view>::format(n, ctx);
} }
}; };
@ -236,8 +235,7 @@ template <>
struct fmt::formatter<Service::PSC::Time::RuleVersion> : fmt::formatter<fmt::string_view> { struct fmt::formatter<Service::PSC::Time::RuleVersion> : fmt::formatter<fmt::string_view> {
template <typename FormatContext> template <typename FormatContext>
auto format(const Service::PSC::Time::RuleVersion& version, FormatContext& ctx) const { auto format(const Service::PSC::Time::RuleVersion& version, FormatContext& ctx) const {
std::string_view v{version.data(), version.size()}; return formatter<string_view>::format(version.data(), ctx);
return formatter<string_view>::format(v, ctx);
} }
}; };

View file

@ -120,11 +120,8 @@ Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& c
context, context.steady_time_point.clock_source_id.RawString(), accuracy); context, context.steady_time_point.clock_source_id.RawString(), accuracy);
// TODO this is a hack! The network clock should be updated independently, from the ntc service // TODO this is a hack! The network clock should be updated independently, from the ntc service
// and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot // and maybe elsewhere. We do not do that, so fix the clock to the local clock.
// to avoid it being stuck at 0.
if (context == Service::PSC::Time::SystemClockContext{}) {
m_local_system_clock.GetContext(context); m_local_system_clock.GetContext(context);
}
m_network_system_clock.SetContextWriter(m_network_system_context_writer); m_network_system_clock.SetContextWriter(m_network_system_context_writer);
m_network_system_clock.Initialize(context, accuracy); m_network_system_clock.Initialize(context, accuracy);
@ -138,13 +135,6 @@ Result ServiceManager::SetupStandardUserSystemClockCore(bool automatic_correctio
LOG_DEBUG(Service_Time, "called. automatic_correction={} time_point={} clock_source_id={}", LOG_DEBUG(Service_Time, "called. automatic_correction={} time_point={} clock_source_id={}",
automatic_correction, time_point, time_point.clock_source_id.RawString()); automatic_correction, time_point, time_point.clock_source_id.RawString());
// TODO this is a hack! The user clock should be updated independently, from the ntc service
// and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot
// to avoid it being stuck at 0.
if (time_point == Service::PSC::Time::SteadyClockTimePoint{}) {
m_local_system_clock.GetCurrentTimePoint(time_point);
}
m_user_system_clock.SetAutomaticCorrection(automatic_correction); m_user_system_clock.SetAutomaticCorrection(automatic_correction);
m_user_system_clock.SetTimePointAndSignal(time_point); m_user_system_clock.SetTimePointAndSignal(time_point);
m_user_system_clock.SetInitialized(); m_user_system_clock.SetInitialized();

View file

@ -404,7 +404,10 @@ struct NpadPowerInfo {
static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size"); static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
struct LedPattern { struct LedPattern {
explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) { LedPattern() {
raw = 0;
}
LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
position1.Assign(light1); position1.Assign(light1);
position2.Assign(light2); position2.Assign(light2);
position3.Assign(light3); position3.Assign(light3);

View file

@ -956,17 +956,6 @@ Result NPad::SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
return ResultSuccess; return ResultSuccess;
} }
Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return ResultInvalidNpadId;
}
const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid();
const auto& controller = GetControllerFromNpadIdType(aruid, npad_id).device;
pattern = controller->GetLedPattern();
return ResultSuccess;
}
Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid, Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
Core::HID::NpadIdType npad_id) const { Core::HID::NpadIdType npad_id) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};

View file

@ -97,8 +97,6 @@ public:
Result ResetIsSixAxisSensorDeviceNewlyAssigned( Result ResetIsSixAxisSensorDeviceNewlyAssigned(
u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle); u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle);
Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
Result IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid, Result IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
Core::HID::NpadIdType npad_id) const; Core::HID::NpadIdType npad_id) const;
Result EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id, Result EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id,