summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar liamwhite2024-02-01 11:33:55 -0500
committerGravatar GitHub2024-02-01 11:33:55 -0500
commitc9ff4b9de40177ff858925e4320fbbc47c0208f9 (patch)
treebb0dc29bc6a3522905985de45d87933b616f5d5c
parentMerge pull request #12780 from german77/touch_resource5 (diff)
parentservice: capsrv: Migrate to new IPC (diff)
downloadyuzu-c9ff4b9de40177ff858925e4320fbbc47c0208f9.tar.gz
yuzu-c9ff4b9de40177ff858925e4320fbbc47c0208f9.tar.xz
yuzu-c9ff4b9de40177ff858925e4320fbbc47c0208f9.zip
Merge pull request #12848 from german77/caps-interface
service: capsrv: Migrate to new IPC
-rw-r--r--src/core/hle/service/caps/caps_a.cpp156
-rw-r--r--src/core/hle/service/caps/caps_a.h34
-rw-r--r--src/core/hle/service/caps/caps_c.cpp16
-rw-r--r--src/core/hle/service/caps/caps_c.h5
-rw-r--r--src/core/hle/service/caps/caps_manager.cpp61
-rw-r--r--src/core/hle/service/caps/caps_manager.h16
-rw-r--r--src/core/hle/service/caps/caps_ss.cpp82
-rw-r--r--src/core/hle/service/caps/caps_ss.h18
-rw-r--r--src/core/hle/service/caps/caps_su.cpp87
-rw-r--r--src/core/hle/service/caps/caps_su.h18
-rw-r--r--src/core/hle/service/caps/caps_types.h32
-rw-r--r--src/core/hle/service/caps/caps_u.cpp110
-rw-r--r--src/core/hle/service/caps/caps_u.h16
13 files changed, 263 insertions, 388 deletions
diff --git a/src/core/hle/service/caps/caps_a.cpp b/src/core/hle/service/caps/caps_a.cpp
index 69acb3a8b..47ff072c5 100644
--- a/src/core/hle/service/caps/caps_a.cpp
+++ b/src/core/hle/service/caps/caps_a.cpp
@@ -5,7 +5,7 @@
5#include "core/hle/service/caps/caps_a.h" 5#include "core/hle/service/caps/caps_a.h"
6#include "core/hle/service/caps/caps_manager.h" 6#include "core/hle/service/caps/caps_manager.h"
7#include "core/hle/service/caps/caps_result.h" 7#include "core/hle/service/caps/caps_result.h"
8#include "core/hle/service/caps/caps_types.h" 8#include "core/hle/service/cmif_serialization.h"
9#include "core/hle/service/ipc_helpers.h" 9#include "core/hle/service/ipc_helpers.h"
10 10
11namespace Service::Capture { 11namespace Service::Capture {
@@ -18,9 +18,9 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
18 {0, nullptr, "GetAlbumFileCount"}, 18 {0, nullptr, "GetAlbumFileCount"},
19 {1, nullptr, "GetAlbumFileList"}, 19 {1, nullptr, "GetAlbumFileList"},
20 {2, nullptr, "LoadAlbumFile"}, 20 {2, nullptr, "LoadAlbumFile"},
21 {3, &IAlbumAccessorService::DeleteAlbumFile, "DeleteAlbumFile"}, 21 {3, C<&IAlbumAccessorService::DeleteAlbumFile>, "DeleteAlbumFile"},
22 {4, nullptr, "StorageCopyAlbumFile"}, 22 {4, nullptr, "StorageCopyAlbumFile"},
23 {5, &IAlbumAccessorService::IsAlbumMounted, "IsAlbumMounted"}, 23 {5, C<&IAlbumAccessorService::IsAlbumMounted>, "IsAlbumMounted"},
24 {6, nullptr, "GetAlbumUsage"}, 24 {6, nullptr, "GetAlbumUsage"},
25 {7, nullptr, "GetAlbumFileSize"}, 25 {7, nullptr, "GetAlbumFileSize"},
26 {8, nullptr, "LoadAlbumFileThumbnail"}, 26 {8, nullptr, "LoadAlbumFileThumbnail"},
@@ -33,18 +33,18 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
33 {15, nullptr, "GetAlbumUsage3"}, 33 {15, nullptr, "GetAlbumUsage3"},
34 {16, nullptr, "GetAlbumMountResult"}, 34 {16, nullptr, "GetAlbumMountResult"},
35 {17, nullptr, "GetAlbumUsage16"}, 35 {17, nullptr, "GetAlbumUsage16"},
36 {18, &IAlbumAccessorService::Unknown18, "Unknown18"}, 36 {18, C<&IAlbumAccessorService::Unknown18>, "Unknown18"},
37 {19, nullptr, "Unknown19"}, 37 {19, nullptr, "Unknown19"},
38 {100, nullptr, "GetAlbumFileCountEx0"}, 38 {100, nullptr, "GetAlbumFileCountEx0"},
39 {101, &IAlbumAccessorService::GetAlbumFileListEx0, "GetAlbumFileListEx0"}, 39 {101, C<&IAlbumAccessorService::GetAlbumFileListEx0>, "GetAlbumFileListEx0"},
40 {202, nullptr, "SaveEditedScreenShot"}, 40 {202, nullptr, "SaveEditedScreenShot"},
41 {301, nullptr, "GetLastThumbnail"}, 41 {301, nullptr, "GetLastThumbnail"},
42 {302, nullptr, "GetLastOverlayMovieThumbnail"}, 42 {302, nullptr, "GetLastOverlayMovieThumbnail"},
43 {401, &IAlbumAccessorService::GetAutoSavingStorage, "GetAutoSavingStorage"}, 43 {401, C<&IAlbumAccessorService::GetAutoSavingStorage>, "GetAutoSavingStorage"},
44 {501, nullptr, "GetRequiredStorageSpaceSizeToCopyAll"}, 44 {501, nullptr, "GetRequiredStorageSpaceSizeToCopyAll"},
45 {1001, nullptr, "LoadAlbumScreenShotThumbnailImageEx0"}, 45 {1001, nullptr, "LoadAlbumScreenShotThumbnailImageEx0"},
46 {1002, &IAlbumAccessorService::LoadAlbumScreenShotImageEx1, "LoadAlbumScreenShotImageEx1"}, 46 {1002, C<&IAlbumAccessorService::LoadAlbumScreenShotImageEx1>, "LoadAlbumScreenShotImageEx1"},
47 {1003, &IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1, "LoadAlbumScreenShotThumbnailImageEx1"}, 47 {1003, C<&IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1>, "LoadAlbumScreenShotThumbnailImageEx1"},
48 {8001, nullptr, "ForceAlbumUnmounted"}, 48 {8001, nullptr, "ForceAlbumUnmounted"},
49 {8002, nullptr, "ResetAlbumMountStatus"}, 49 {8002, nullptr, "ResetAlbumMountStatus"},
50 {8011, nullptr, "RefreshAlbumCache"}, 50 {8011, nullptr, "RefreshAlbumCache"},
@@ -62,138 +62,70 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
62 62
63IAlbumAccessorService::~IAlbumAccessorService() = default; 63IAlbumAccessorService::~IAlbumAccessorService() = default;
64 64
65void IAlbumAccessorService::DeleteAlbumFile(HLERequestContext& ctx) { 65Result IAlbumAccessorService::DeleteAlbumFile(AlbumFileId file_id) {
66 IPC::RequestParser rp{ctx};
67 const auto file_id{rp.PopRaw<AlbumFileId>()};
68
69 LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}", 66 LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}",
70 file_id.application_id, file_id.storage, file_id.type); 67 file_id.application_id, file_id.storage, file_id.type);
71 68
72 Result result = manager->DeleteAlbumFile(file_id); 69 const Result result = manager->DeleteAlbumFile(file_id);
73 result = TranslateResult(result); 70 R_RETURN(TranslateResult(result));
74
75 IPC::ResponseBuilder rb{ctx, 2};
76 rb.Push(result);
77} 71}
78 72
79void IAlbumAccessorService::IsAlbumMounted(HLERequestContext& ctx) { 73Result IAlbumAccessorService::IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage) {
80 IPC::RequestParser rp{ctx};
81 const auto storage{rp.PopEnum<AlbumStorage>()};
82
83 LOG_INFO(Service_Capture, "called, storage={}", storage); 74 LOG_INFO(Service_Capture, "called, storage={}", storage);
84 75
85 Result result = manager->IsAlbumMounted(storage); 76 const Result result = manager->IsAlbumMounted(storage);
86 const bool is_mounted = result.IsSuccess(); 77 *out_is_mounted = result.IsSuccess();
87 result = TranslateResult(result); 78 R_RETURN(TranslateResult(result));
88
89 IPC::ResponseBuilder rb{ctx, 3};
90 rb.Push(result);
91 rb.Push<u8>(is_mounted);
92} 79}
93 80
94void IAlbumAccessorService::Unknown18(HLERequestContext& ctx) { 81Result IAlbumAccessorService::Unknown18(
95 struct UnknownBuffer { 82 Out<u32> out_buffer_size,
96 INSERT_PADDING_BYTES(0x10); 83 OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_buffer) {
97 };
98 static_assert(sizeof(UnknownBuffer) == 0x10, "UnknownBuffer is an invalid size");
99
100 LOG_WARNING(Service_Capture, "(STUBBED) called"); 84 LOG_WARNING(Service_Capture, "(STUBBED) called");
101 85 *out_buffer_size = 0;
102 std::vector<UnknownBuffer> buffer{}; 86 R_SUCCEED();
103
104 if (!buffer.empty()) {
105 ctx.WriteBuffer(buffer);
106 }
107
108 IPC::ResponseBuilder rb{ctx, 3};
109 rb.Push(ResultSuccess);
110 rb.Push(static_cast<u32>(buffer.size()));
111} 87}
112 88
113void IAlbumAccessorService::GetAlbumFileListEx0(HLERequestContext& ctx) { 89Result IAlbumAccessorService::GetAlbumFileListEx0(
114 IPC::RequestParser rp{ctx}; 90 Out<u64> out_entries_size, AlbumStorage storage, u8 flags,
115 const auto storage{rp.PopEnum<AlbumStorage>()}; 91 OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
116 const auto flags{rp.Pop<u8>()};
117 const auto album_entry_size{ctx.GetWriteBufferNumElements<AlbumEntry>()};
118
119 LOG_INFO(Service_Capture, "called, storage={}, flags={}", storage, flags); 92 LOG_INFO(Service_Capture, "called, storage={}, flags={}", storage, flags);
120 93
121 std::vector<AlbumEntry> entries; 94 const Result result = manager->GetAlbumFileList(out_entries, *out_entries_size, storage, flags);
122 Result result = manager->GetAlbumFileList(entries, storage, flags); 95 R_RETURN(TranslateResult(result));
123 result = TranslateResult(result);
124
125 entries.resize(std::min(album_entry_size, entries.size()));
126
127 if (!entries.empty()) {
128 ctx.WriteBuffer(entries);
129 }
130
131 IPC::ResponseBuilder rb{ctx, 4};
132 rb.Push(result);
133 rb.Push<u64>(entries.size());
134} 96}
135 97
136void IAlbumAccessorService::GetAutoSavingStorage(HLERequestContext& ctx) { 98Result IAlbumAccessorService::GetAutoSavingStorage(Out<bool> out_is_autosaving) {
137 LOG_WARNING(Service_Capture, "(STUBBED) called"); 99 LOG_WARNING(Service_Capture, "(STUBBED) called");
138 100
139 bool is_autosaving{}; 101 const Result result = manager->GetAutoSavingStorage(*out_is_autosaving);
140 Result result = manager->GetAutoSavingStorage(is_autosaving); 102 R_RETURN(TranslateResult(result));
141 result = TranslateResult(result);
142
143 IPC::ResponseBuilder rb{ctx, 3};
144 rb.Push(result);
145 rb.Push<u8>(is_autosaving);
146} 103}
147 104
148void IAlbumAccessorService::LoadAlbumScreenShotImageEx1(HLERequestContext& ctx) { 105Result IAlbumAccessorService::LoadAlbumScreenShotImageEx1(
149 IPC::RequestParser rp{ctx}; 106 const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
150 const auto file_id{rp.PopRaw<AlbumFileId>()}; 107 OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
151 const auto decoder_options{rp.PopRaw<ScreenShotDecodeOption>()}; 108 OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
152 const auto image_buffer_size{ctx.GetWriteBufferSize(1)}; 109 OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
153
154 LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}", 110 LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}",
155 file_id.application_id, file_id.storage, file_id.type, decoder_options.flags); 111 file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
156 112
157 std::vector<u8> image; 113 const Result result =
158 LoadAlbumScreenShotImageOutput image_output; 114 manager->LoadAlbumScreenShotImage(*out_image_output, out_image, file_id, decoder_options);
159 Result result = 115 R_RETURN(TranslateResult(result));
160 manager->LoadAlbumScreenShotImage(image_output, image, file_id, decoder_options);
161 result = TranslateResult(result);
162
163 if (image.size() > image_buffer_size) {
164 result = ResultWorkMemoryError;
165 }
166
167 if (result.IsSuccess()) {
168 ctx.WriteBuffer(image_output, 0);
169 ctx.WriteBuffer(image, 1);
170 }
171
172 IPC::ResponseBuilder rb{ctx, 2};
173 rb.Push(result);
174} 116}
175 117
176void IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1(HLERequestContext& ctx) { 118Result IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1(
177 IPC::RequestParser rp{ctx}; 119 const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
178 const auto file_id{rp.PopRaw<AlbumFileId>()}; 120 OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
179 const auto decoder_options{rp.PopRaw<ScreenShotDecodeOption>()}; 121 OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
180 122 OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
181 LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}", 123 LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}",
182 file_id.application_id, file_id.storage, file_id.type, decoder_options.flags); 124 file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
183 125
184 std::vector<u8> image(ctx.GetWriteBufferSize(1)); 126 const Result result = manager->LoadAlbumScreenShotThumbnail(*out_image_output, out_image,
185 LoadAlbumScreenShotImageOutput image_output; 127 file_id, decoder_options);
186 Result result = 128 R_RETURN(TranslateResult(result));
187 manager->LoadAlbumScreenShotThumbnail(image_output, image, file_id, decoder_options);
188 result = TranslateResult(result);
189
190 if (result.IsSuccess()) {
191 ctx.WriteBuffer(image_output, 0);
192 ctx.WriteBuffer(image, 1);
193 }
194
195 IPC::ResponseBuilder rb{ctx, 2};
196 rb.Push(result);
197} 129}
198 130
199Result IAlbumAccessorService::TranslateResult(Result in_result) { 131Result IAlbumAccessorService::TranslateResult(Result in_result) {
diff --git a/src/core/hle/service/caps/caps_a.h b/src/core/hle/service/caps/caps_a.h
index c90cff71e..2cb9b4547 100644
--- a/src/core/hle/service/caps/caps_a.h
+++ b/src/core/hle/service/caps/caps_a.h
@@ -3,6 +3,8 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/caps/caps_types.h"
7#include "core/hle/service/cmif_types.h"
6#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
7 9
8namespace Core { 10namespace Core {
@@ -19,13 +21,31 @@ public:
19 ~IAlbumAccessorService() override; 21 ~IAlbumAccessorService() override;
20 22
21private: 23private:
22 void DeleteAlbumFile(HLERequestContext& ctx); 24 Result DeleteAlbumFile(AlbumFileId file_id);
23 void IsAlbumMounted(HLERequestContext& ctx); 25
24 void Unknown18(HLERequestContext& ctx); 26 Result IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage);
25 void GetAlbumFileListEx0(HLERequestContext& ctx); 27
26 void GetAutoSavingStorage(HLERequestContext& ctx); 28 Result Unknown18(
27 void LoadAlbumScreenShotImageEx1(HLERequestContext& ctx); 29 Out<u32> out_buffer_size,
28 void LoadAlbumScreenShotThumbnailImageEx1(HLERequestContext& ctx); 30 OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure>
31 out_buffer);
32
33 Result GetAlbumFileListEx0(Out<u64> out_entries_size, AlbumStorage storage, u8 flags,
34 OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries);
35
36 Result GetAutoSavingStorage(Out<bool> out_is_autosaving);
37
38 Result LoadAlbumScreenShotImageEx1(
39 const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
40 OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
41 OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
42 OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
43
44 Result LoadAlbumScreenShotThumbnailImageEx1(
45 const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
46 OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
47 OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
48 OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
29 49
30 Result TranslateResult(Result in_result); 50 Result TranslateResult(Result in_result);
31 51
diff --git a/src/core/hle/service/caps/caps_c.cpp b/src/core/hle/service/caps/caps_c.cpp
index 1e7fe6474..6993c04c2 100644
--- a/src/core/hle/service/caps/caps_c.cpp
+++ b/src/core/hle/service/caps/caps_c.cpp
@@ -6,6 +6,7 @@
6#include "core/hle/service/caps/caps_manager.h" 6#include "core/hle/service/caps/caps_manager.h"
7#include "core/hle/service/caps/caps_result.h" 7#include "core/hle/service/caps/caps_result.h"
8#include "core/hle/service/caps/caps_types.h" 8#include "core/hle/service/caps/caps_types.h"
9#include "core/hle/service/cmif_serialization.h"
9#include "core/hle/service/ipc_helpers.h" 10#include "core/hle/service/ipc_helpers.h"
10 11
11namespace Service::Capture { 12namespace Service::Capture {
@@ -17,7 +18,7 @@ IAlbumControlService::IAlbumControlService(Core::System& system_,
17 static const FunctionInfo functions[] = { 18 static const FunctionInfo functions[] = {
18 {1, nullptr, "CaptureRawImage"}, 19 {1, nullptr, "CaptureRawImage"},
19 {2, nullptr, "CaptureRawImageWithTimeout"}, 20 {2, nullptr, "CaptureRawImageWithTimeout"},
20 {33, &IAlbumControlService::SetShimLibraryVersion, "SetShimLibraryVersion"}, 21 {33, C<&IAlbumControlService::SetShimLibraryVersion>, "SetShimLibraryVersion"},
21 {1001, nullptr, "RequestTakingScreenShot"}, 22 {1001, nullptr, "RequestTakingScreenShot"},
22 {1002, nullptr, "RequestTakingScreenShotWithTimeout"}, 23 {1002, nullptr, "RequestTakingScreenShotWithTimeout"},
23 {1011, nullptr, "NotifyTakingScreenShotRefused"}, 24 {1011, nullptr, "NotifyTakingScreenShotRefused"},
@@ -42,16 +43,11 @@ IAlbumControlService::IAlbumControlService(Core::System& system_,
42 43
43IAlbumControlService::~IAlbumControlService() = default; 44IAlbumControlService::~IAlbumControlService() = default;
44 45
45void IAlbumControlService::SetShimLibraryVersion(HLERequestContext& ctx) { 46Result IAlbumControlService::SetShimLibraryVersion(ShimLibraryVersion library_version,
46 IPC::RequestParser rp{ctx}; 47 ClientAppletResourceUserId aruid) {
47 const auto library_version{rp.Pop<u64>()};
48 const auto applet_resource_user_id{rp.Pop<u64>()};
49
50 LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", 48 LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
51 library_version, applet_resource_user_id); 49 library_version, aruid.pid);
52 50 R_SUCCEED();
53 IPC::ResponseBuilder rb{ctx, 2};
54 rb.Push(ResultSuccess);
55} 51}
56 52
57} // namespace Service::Capture 53} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_c.h b/src/core/hle/service/caps/caps_c.h
index 92ba242db..0ecdfa114 100644
--- a/src/core/hle/service/caps/caps_c.h
+++ b/src/core/hle/service/caps/caps_c.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/cmif_types.h"
6#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
7 8
8namespace Core { 9namespace Core {
@@ -11,6 +12,7 @@ class System;
11 12
12namespace Service::Capture { 13namespace Service::Capture {
13class AlbumManager; 14class AlbumManager;
15enum class ShimLibraryVersion : u64;
14 16
15class IAlbumControlService final : public ServiceFramework<IAlbumControlService> { 17class IAlbumControlService final : public ServiceFramework<IAlbumControlService> {
16public: 18public:
@@ -19,7 +21,8 @@ public:
19 ~IAlbumControlService() override; 21 ~IAlbumControlService() override;
20 22
21private: 23private:
22 void SetShimLibraryVersion(HLERequestContext& ctx); 24 Result SetShimLibraryVersion(ShimLibraryVersion library_version,
25 ClientAppletResourceUserId aruid);
23 26
24 std::shared_ptr<AlbumManager> manager = nullptr; 27 std::shared_ptr<AlbumManager> manager = nullptr;
25}; 28};
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp
index 3a22b135f..7f0bc127f 100644
--- a/src/core/hle/service/caps/caps_manager.cpp
+++ b/src/core/hle/service/caps/caps_manager.cpp
@@ -58,8 +58,8 @@ Result AlbumManager::IsAlbumMounted(AlbumStorage storage) {
58 return is_mounted ? ResultSuccess : ResultIsNotMounted; 58 return is_mounted ? ResultSuccess : ResultIsNotMounted;
59} 59}
60 60
61Result AlbumManager::GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage, 61Result AlbumManager::GetAlbumFileList(std::span<AlbumEntry> out_entries, u64& out_entries_count,
62 u8 flags) const { 62 AlbumStorage storage, u8 flags) const {
63 if (storage > AlbumStorage::Sd) { 63 if (storage > AlbumStorage::Sd) {
64 return ResultInvalidStorage; 64 return ResultInvalidStorage;
65 } 65 }
@@ -72,51 +72,55 @@ Result AlbumManager::GetAlbumFileList(std::vector<AlbumEntry>& out_entries, Albu
72 if (file_id.storage != storage) { 72 if (file_id.storage != storage) {
73 continue; 73 continue;
74 } 74 }
75 if (out_entries.size() >= SdAlbumFileLimit) { 75 if (out_entries_count >= SdAlbumFileLimit) {
76 break;
77 }
78 if (out_entries_count >= out_entries.size()) {
76 break; 79 break;
77 } 80 }
78 81
79 const auto entry_size = Common::FS::GetSize(path); 82 const auto entry_size = Common::FS::GetSize(path);
80 out_entries.push_back({ 83 out_entries[out_entries_count++] = {
81 .entry_size = entry_size, 84 .entry_size = entry_size,
82 .file_id = file_id, 85 .file_id = file_id,
83 }); 86 };
84 } 87 }
85 88
86 return ResultSuccess; 89 return ResultSuccess;
87} 90}
88 91
89Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries, 92Result AlbumManager::GetAlbumFileList(std::span<ApplicationAlbumFileEntry> out_entries,
90 ContentType content_type, s64 start_posix_time, 93 u64& out_entries_count, ContentType content_type,
91 s64 end_posix_time, u64 aruid) const { 94 s64 start_posix_time, s64 end_posix_time, u64 aruid) const {
92 if (!is_mounted) { 95 if (!is_mounted) {
93 return ResultIsNotMounted; 96 return ResultIsNotMounted;
94 } 97 }
95 98
96 std::vector<ApplicationAlbumEntry> album_entries; 99 std::vector<ApplicationAlbumEntry> album_entries(out_entries.size());
97 const auto start_date = ConvertToAlbumDateTime(start_posix_time); 100 const auto start_date = ConvertToAlbumDateTime(start_posix_time);
98 const auto end_date = ConvertToAlbumDateTime(end_posix_time); 101 const auto end_date = ConvertToAlbumDateTime(end_posix_time);
99 const auto result = GetAlbumFileList(album_entries, content_type, start_date, end_date, aruid); 102 const auto result = GetAlbumFileList(album_entries, out_entries_count, content_type, start_date,
103 end_date, aruid);
100 104
101 if (result.IsError()) { 105 if (result.IsError()) {
102 return result; 106 return result;
103 } 107 }
104 108
105 for (const auto& album_entry : album_entries) { 109 for (std::size_t i = 0; i < out_entries_count; i++) {
106 ApplicationAlbumFileEntry entry{ 110 out_entries[i] = {
107 .entry = album_entry, 111 .entry = album_entries[i],
108 .datetime = album_entry.datetime, 112 .datetime = album_entries[i].datetime,
109 .unknown = {}, 113 .unknown = {},
110 }; 114 };
111 out_entries.push_back(entry);
112 } 115 }
113 116
114 return ResultSuccess; 117 return ResultSuccess;
115} 118}
116 119
117Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries, 120Result AlbumManager::GetAlbumFileList(std::span<ApplicationAlbumEntry> out_entries,
118 ContentType content_type, AlbumFileDateTime start_date, 121 u64& out_entries_count, ContentType content_type,
119 AlbumFileDateTime end_date, u64 aruid) const { 122 AlbumFileDateTime start_date, AlbumFileDateTime end_date,
123 u64 aruid) const {
120 if (!is_mounted) { 124 if (!is_mounted) {
121 return ResultIsNotMounted; 125 return ResultIsNotMounted;
122 } 126 }
@@ -131,12 +135,15 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_en
131 if (file_id.date < end_date) { 135 if (file_id.date < end_date) {
132 continue; 136 continue;
133 } 137 }
134 if (out_entries.size() >= SdAlbumFileLimit) { 138 if (out_entries_count >= SdAlbumFileLimit) {
139 break;
140 }
141 if (out_entries_count >= out_entries.size()) {
135 break; 142 break;
136 } 143 }
137 144
138 const auto entry_size = Common::FS::GetSize(path); 145 const auto entry_size = Common::FS::GetSize(path);
139 ApplicationAlbumEntry entry{ 146 out_entries[out_entries_count++] = {
140 .size = entry_size, 147 .size = entry_size,
141 .hash{}, 148 .hash{},
142 .datetime = file_id.date, 149 .datetime = file_id.date,
@@ -144,7 +151,6 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_en
144 .content = content_type, 151 .content = content_type,
145 .unknown = 1, 152 .unknown = 1,
146 }; 153 };
147 out_entries.push_back(entry);
148 } 154 }
149 155
150 return ResultSuccess; 156 return ResultSuccess;
@@ -156,8 +162,7 @@ Result AlbumManager::GetAutoSavingStorage(bool& out_is_autosaving) const {
156} 162}
157 163
158Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output, 164Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output,
159 std::vector<u8>& out_image, 165 std::span<u8> out_image, const AlbumFileId& file_id,
160 const AlbumFileId& file_id,
161 const ScreenShotDecodeOption& decoder_options) const { 166 const ScreenShotDecodeOption& decoder_options) const {
162 if (file_id.storage > AlbumStorage::Sd) { 167 if (file_id.storage > AlbumStorage::Sd) {
163 return ResultInvalidStorage; 168 return ResultInvalidStorage;
@@ -176,7 +181,9 @@ Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& ou
176 .orientation = AlbumImageOrientation::None, 181 .orientation = AlbumImageOrientation::None,
177 .unknown_1{}, 182 .unknown_1{},
178 .unknown_2{}, 183 .unknown_2{},
184 .pad163{},
179 }, 185 },
186 .pad179{},
180 }; 187 };
181 188
182 std::filesystem::path path; 189 std::filesystem::path path;
@@ -186,14 +193,12 @@ Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& ou
186 return result; 193 return result;
187 } 194 }
188 195
189 out_image.resize(out_image_output.height * out_image_output.width * STBI_rgb_alpha);
190
191 return LoadImage(out_image, path, static_cast<int>(out_image_output.width), 196 return LoadImage(out_image, path, static_cast<int>(out_image_output.width),
192 +static_cast<int>(out_image_output.height), decoder_options.flags); 197 +static_cast<int>(out_image_output.height), decoder_options.flags);
193} 198}
194 199
195Result AlbumManager::LoadAlbumScreenShotThumbnail( 200Result AlbumManager::LoadAlbumScreenShotThumbnail(
196 LoadAlbumScreenShotImageOutput& out_image_output, std::vector<u8>& out_image, 201 LoadAlbumScreenShotImageOutput& out_image_output, std::span<u8> out_image,
197 const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options) const { 202 const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options) const {
198 if (file_id.storage > AlbumStorage::Sd) { 203 if (file_id.storage > AlbumStorage::Sd) {
199 return ResultInvalidStorage; 204 return ResultInvalidStorage;
@@ -212,7 +217,9 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(
212 .orientation = AlbumImageOrientation::None, 217 .orientation = AlbumImageOrientation::None,
213 .unknown_1{}, 218 .unknown_1{},
214 .unknown_2{}, 219 .unknown_2{},
220 .pad163{},
215 }, 221 },
222 .pad179{},
216 }; 223 };
217 224
218 std::filesystem::path path; 225 std::filesystem::path path;
@@ -222,8 +229,6 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(
222 return result; 229 return result;
223 } 230 }
224 231
225 out_image.resize(out_image_output.height * out_image_output.width * STBI_rgb_alpha);
226
227 return LoadImage(out_image, path, static_cast<int>(out_image_output.width), 232 return LoadImage(out_image, path, static_cast<int>(out_image_output.width),
228 +static_cast<int>(out_image_output.height), decoder_options.flags); 233 +static_cast<int>(out_image_output.height), decoder_options.flags);
229} 234}
diff --git a/src/core/hle/service/caps/caps_manager.h b/src/core/hle/service/caps/caps_manager.h
index 6fd34f589..893a9075a 100644
--- a/src/core/hle/service/caps/caps_manager.h
+++ b/src/core/hle/service/caps/caps_manager.h
@@ -42,20 +42,20 @@ public:
42 42
43 Result DeleteAlbumFile(const AlbumFileId& file_id); 43 Result DeleteAlbumFile(const AlbumFileId& file_id);
44 Result IsAlbumMounted(AlbumStorage storage); 44 Result IsAlbumMounted(AlbumStorage storage);
45 Result GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage, 45 Result GetAlbumFileList(std::span<AlbumEntry> out_entries, u64& out_entries_count,
46 u8 flags) const; 46 AlbumStorage storage, u8 flags) const;
47 Result GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries, 47 Result GetAlbumFileList(std::span<ApplicationAlbumFileEntry> out_entries,
48 ContentType content_type, s64 start_posix_time, s64 end_posix_time, 48 u64& out_entries_count, ContentType content_type, s64 start_posix_time,
49 u64 aruid) const; 49 s64 end_posix_time, u64 aruid) const;
50 Result GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries, 50 Result GetAlbumFileList(std::span<ApplicationAlbumEntry> out_entries, u64& out_entries_count,
51 ContentType content_type, AlbumFileDateTime start_date, 51 ContentType content_type, AlbumFileDateTime start_date,
52 AlbumFileDateTime end_date, u64 aruid) const; 52 AlbumFileDateTime end_date, u64 aruid) const;
53 Result GetAutoSavingStorage(bool& out_is_autosaving) const; 53 Result GetAutoSavingStorage(bool& out_is_autosaving) const;
54 Result LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output, 54 Result LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output,
55 std::vector<u8>& out_image, const AlbumFileId& file_id, 55 std::span<u8> out_image, const AlbumFileId& file_id,
56 const ScreenShotDecodeOption& decoder_options) const; 56 const ScreenShotDecodeOption& decoder_options) const;
57 Result LoadAlbumScreenShotThumbnail(LoadAlbumScreenShotImageOutput& out_image_output, 57 Result LoadAlbumScreenShotThumbnail(LoadAlbumScreenShotImageOutput& out_image_output,
58 std::vector<u8>& out_image, const AlbumFileId& file_id, 58 std::span<u8> out_image, const AlbumFileId& file_id,
59 const ScreenShotDecodeOption& decoder_options) const; 59 const ScreenShotDecodeOption& decoder_options) const;
60 60
61 Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute, 61 Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
diff --git a/src/core/hle/service/caps/caps_ss.cpp b/src/core/hle/service/caps/caps_ss.cpp
index eab023568..dfa7f1a84 100644
--- a/src/core/hle/service/caps/caps_ss.cpp
+++ b/src/core/hle/service/caps/caps_ss.cpp
@@ -3,10 +3,9 @@
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/service/caps/caps_manager.h" 5#include "core/hle/service/caps/caps_manager.h"
6#include "core/hle/service/caps/caps_types.h"
7#include "core/hle/service/ipc_helpers.h"
8
9#include "core/hle/service/caps/caps_ss.h" 6#include "core/hle/service/caps/caps_ss.h"
7#include "core/hle/service/cmif_serialization.h"
8#include "core/hle/service/ipc_helpers.h"
10 9
11namespace Service::Capture { 10namespace Service::Capture {
12 11
@@ -17,9 +16,9 @@ IScreenShotService::IScreenShotService(Core::System& system_,
17 static const FunctionInfo functions[] = { 16 static const FunctionInfo functions[] = {
18 {201, nullptr, "SaveScreenShot"}, 17 {201, nullptr, "SaveScreenShot"},
19 {202, nullptr, "SaveEditedScreenShot"}, 18 {202, nullptr, "SaveEditedScreenShot"},
20 {203, &IScreenShotService::SaveScreenShotEx0, "SaveScreenShotEx0"}, 19 {203, C<&IScreenShotService::SaveScreenShotEx0>, "SaveScreenShotEx0"},
21 {204, nullptr, "SaveEditedScreenShotEx0"}, 20 {204, nullptr, "SaveEditedScreenShotEx0"},
22 {206, &IScreenShotService::SaveEditedScreenShotEx1, "SaveEditedScreenShotEx1"}, 21 {206, C<&IScreenShotService::SaveEditedScreenShotEx1>, "SaveEditedScreenShotEx1"},
23 {208, nullptr, "SaveScreenShotOfMovieEx1"}, 22 {208, nullptr, "SaveScreenShotOfMovieEx1"},
24 {1000, nullptr, "Unknown1000"}, 23 {1000, nullptr, "Unknown1000"},
25 }; 24 };
@@ -30,69 +29,38 @@ IScreenShotService::IScreenShotService(Core::System& system_,
30 29
31IScreenShotService::~IScreenShotService() = default; 30IScreenShotService::~IScreenShotService() = default;
32 31
33void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) { 32Result IScreenShotService::SaveScreenShotEx0(
34 IPC::RequestParser rp{ctx}; 33 Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
35 struct Parameters { 34 AlbumReportOption report_option, ClientAppletResourceUserId aruid,
36 ScreenShotAttribute attribute{}; 35 InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
37 AlbumReportOption report_option{}; 36 image_data_buffer) {
38 INSERT_PADDING_BYTES(0x4);
39 u64 applet_resource_user_id{};
40 };
41 static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size.");
42
43 const auto parameters{rp.PopRaw<Parameters>()};
44 const auto image_data_buffer = ctx.ReadBuffer();
45
46 LOG_INFO(Service_Capture, 37 LOG_INFO(Service_Capture,
47 "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}", 38 "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}",
48 parameters.report_option, image_data_buffer.size(), 39 report_option, image_data_buffer.size(), aruid.pid);
49 parameters.applet_resource_user_id);
50 40
51 ApplicationAlbumEntry entry{};
52 manager->FlipVerticallyOnWrite(false); 41 manager->FlipVerticallyOnWrite(false);
53 const auto result = 42 R_RETURN(manager->SaveScreenShot(*out_entry, attribute, report_option, image_data_buffer,
54 manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, 43 aruid.pid));
55 image_data_buffer, parameters.applet_resource_user_id);
56
57 IPC::ResponseBuilder rb{ctx, 10};
58 rb.Push(result);
59 rb.PushRaw(entry);
60} 44}
61 45
62void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) { 46Result IScreenShotService::SaveEditedScreenShotEx1(
63 IPC::RequestParser rp{ctx}; 47 Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute, u64 width,
64 struct Parameters { 48 u64 height, u64 thumbnail_width, u64 thumbnail_height, const AlbumFileId& file_id,
65 ScreenShotAttribute attribute; 49 const InLargeData<std::array<u8, 0x400>, BufferAttr_HipcMapAlias> application_data_buffer,
66 u64 width; 50 const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
67 u64 height; 51 image_data_buffer,
68 u64 thumbnail_width; 52 const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
69 u64 thumbnail_height; 53 thumbnail_image_data_buffer) {
70 AlbumFileId file_id;
71 };
72 static_assert(sizeof(Parameters) == 0x78, "Parameters has incorrect size.");
73
74 const auto parameters{rp.PopRaw<Parameters>()};
75 const auto application_data_buffer = ctx.ReadBuffer(0);
76 const auto image_data_buffer = ctx.ReadBuffer(1);
77 const auto thumbnail_image_data_buffer = ctx.ReadBuffer(2);
78
79 LOG_INFO(Service_Capture, 54 LOG_INFO(Service_Capture,
80 "called, width={}, height={}, thumbnail_width={}, thumbnail_height={}, " 55 "called, width={}, height={}, thumbnail_width={}, thumbnail_height={}, "
81 "application_id={:016x}, storage={}, type={}, app_data_buffer_size={}, " 56 "application_id={:016x}, storage={}, type={}, "
82 "image_data_buffer_size={}, thumbnail_image_buffer_size={}", 57 "image_data_buffer_size={}, thumbnail_image_buffer_size={}",
83 parameters.width, parameters.height, parameters.thumbnail_width, 58 width, height, thumbnail_width, thumbnail_height, file_id.application_id,
84 parameters.thumbnail_height, parameters.file_id.application_id, 59 file_id.storage, file_id.type, image_data_buffer.size(),
85 parameters.file_id.storage, parameters.file_id.type, application_data_buffer.size(), 60 thumbnail_image_data_buffer.size());
86 image_data_buffer.size(), thumbnail_image_data_buffer.size());
87 61
88 ApplicationAlbumEntry entry{};
89 manager->FlipVerticallyOnWrite(false); 62 manager->FlipVerticallyOnWrite(false);
90 const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute, 63 R_RETURN(manager->SaveEditedScreenShot(*out_entry, attribute, file_id, image_data_buffer));
91 parameters.file_id, image_data_buffer);
92
93 IPC::ResponseBuilder rb{ctx, 10};
94 rb.Push(result);
95 rb.PushRaw(entry);
96} 64}
97 65
98} // namespace Service::Capture 66} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_ss.h b/src/core/hle/service/caps/caps_ss.h
index a7e9972ab..da4b4cc5f 100644
--- a/src/core/hle/service/caps/caps_ss.h
+++ b/src/core/hle/service/caps/caps_ss.h
@@ -3,6 +3,8 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/caps/caps_types.h"
7#include "core/hle/service/cmif_types.h"
6#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
7 9
8namespace Core { 10namespace Core {
@@ -17,8 +19,20 @@ public:
17 ~IScreenShotService() override; 19 ~IScreenShotService() override;
18 20
19private: 21private:
20 void SaveScreenShotEx0(HLERequestContext& ctx); 22 Result SaveScreenShotEx0(
21 void SaveEditedScreenShotEx1(HLERequestContext& ctx); 23 Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
24 AlbumReportOption report_option, ClientAppletResourceUserId aruid,
25 InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
26 image_data_buffer);
27
28 Result SaveEditedScreenShotEx1(
29 Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute, u64 width,
30 u64 height, u64 thumbnail_width, u64 thumbnail_height, const AlbumFileId& file_id,
31 const InLargeData<std::array<u8, 0x400>, BufferAttr_HipcMapAlias> application_data_buffer,
32 const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
33 image_data_buffer,
34 const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
35 thumbnail_image_data_buffer);
22 36
23 std::shared_ptr<AlbumManager> manager; 37 std::shared_ptr<AlbumManager> manager;
24}; 38};
diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp
index 296b07b00..528f364f5 100644
--- a/src/core/hle/service/caps/caps_su.cpp
+++ b/src/core/hle/service/caps/caps_su.cpp
@@ -6,6 +6,7 @@
6#include "core/hle/service/caps/caps_manager.h" 6#include "core/hle/service/caps/caps_manager.h"
7#include "core/hle/service/caps/caps_su.h" 7#include "core/hle/service/caps/caps_su.h"
8#include "core/hle/service/caps/caps_types.h" 8#include "core/hle/service/caps/caps_types.h"
9#include "core/hle/service/cmif_serialization.h"
9#include "core/hle/service/ipc_helpers.h" 10#include "core/hle/service/ipc_helpers.h"
10#include "video_core/renderer_base.h" 11#include "video_core/renderer_base.h"
11 12
@@ -16,10 +17,10 @@ IScreenShotApplicationService::IScreenShotApplicationService(
16 : ServiceFramework{system_, "caps:su"}, manager{album_manager} { 17 : ServiceFramework{system_, "caps:su"}, manager{album_manager} {
17 // clang-format off 18 // clang-format off
18 static const FunctionInfo functions[] = { 19 static const FunctionInfo functions[] = {
19 {32, &IScreenShotApplicationService::SetShimLibraryVersion, "SetShimLibraryVersion"}, 20 {32, C<&IScreenShotApplicationService::SetShimLibraryVersion>, "SetShimLibraryVersion"},
20 {201, nullptr, "SaveScreenShot"}, 21 {201, nullptr, "SaveScreenShot"},
21 {203, &IScreenShotApplicationService::SaveScreenShotEx0, "SaveScreenShotEx0"}, 22 {203, C<&IScreenShotApplicationService::SaveScreenShotEx0>, "SaveScreenShotEx0"},
22 {205, &IScreenShotApplicationService::SaveScreenShotEx1, "SaveScreenShotEx1"}, 23 {205, C<&IScreenShotApplicationService::SaveScreenShotEx1>, "SaveScreenShotEx1"},
23 {210, nullptr, "SaveScreenShotEx2"}, 24 {210, nullptr, "SaveScreenShotEx2"},
24 }; 25 };
25 // clang-format on 26 // clang-format on
@@ -29,77 +30,40 @@ IScreenShotApplicationService::IScreenShotApplicationService(
29 30
30IScreenShotApplicationService::~IScreenShotApplicationService() = default; 31IScreenShotApplicationService::~IScreenShotApplicationService() = default;
31 32
32void IScreenShotApplicationService::SetShimLibraryVersion(HLERequestContext& ctx) { 33Result IScreenShotApplicationService::SetShimLibraryVersion(ShimLibraryVersion library_version,
33 IPC::RequestParser rp{ctx}; 34 ClientAppletResourceUserId aruid) {
34 const auto library_version{rp.Pop<u64>()};
35 const auto applet_resource_user_id{rp.Pop<u64>()};
36
37 LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", 35 LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
38 library_version, applet_resource_user_id); 36 library_version, aruid.pid);
39 37 R_SUCCEED();
40 IPC::ResponseBuilder rb{ctx, 2};
41 rb.Push(ResultSuccess);
42} 38}
43 39
44void IScreenShotApplicationService::SaveScreenShotEx0(HLERequestContext& ctx) { 40Result IScreenShotApplicationService::SaveScreenShotEx0(
45 IPC::RequestParser rp{ctx}; 41 Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
46 struct Parameters { 42 AlbumReportOption report_option, ClientAppletResourceUserId aruid,
47 ScreenShotAttribute attribute{}; 43 InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
48 AlbumReportOption report_option{}; 44 image_data_buffer) {
49 INSERT_PADDING_BYTES(0x4);
50 u64 applet_resource_user_id{};
51 };
52 static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size.");
53
54 const auto parameters{rp.PopRaw<Parameters>()};
55 const auto image_data_buffer = ctx.ReadBuffer();
56
57 LOG_INFO(Service_Capture, 45 LOG_INFO(Service_Capture,
58 "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}", 46 "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}",
59 parameters.report_option, image_data_buffer.size(), 47 report_option, image_data_buffer.size(), aruid.pid);
60 parameters.applet_resource_user_id);
61 48
62 ApplicationAlbumEntry entry{};
63 manager->FlipVerticallyOnWrite(false); 49 manager->FlipVerticallyOnWrite(false);
64 const auto result = 50 R_RETURN(manager->SaveScreenShot(*out_entry, attribute, report_option, image_data_buffer,
65 manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, 51 aruid.pid));
66 image_data_buffer, parameters.applet_resource_user_id);
67
68 IPC::ResponseBuilder rb{ctx, 10};
69 rb.Push(result);
70 rb.PushRaw(entry);
71} 52}
72 53
73void IScreenShotApplicationService::SaveScreenShotEx1(HLERequestContext& ctx) { 54Result IScreenShotApplicationService::SaveScreenShotEx1(
74 IPC::RequestParser rp{ctx}; 55 Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
75 struct Parameters { 56 AlbumReportOption report_option, ClientAppletResourceUserId aruid,
76 ScreenShotAttribute attribute{}; 57 const InLargeData<ApplicationData, BufferAttr_HipcMapAlias> app_data_buffer,
77 AlbumReportOption report_option{}; 58 const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
78 INSERT_PADDING_BYTES(0x4); 59 image_data_buffer) {
79 u64 applet_resource_user_id{};
80 };
81 static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size.");
82
83 const auto parameters{rp.PopRaw<Parameters>()};
84 const auto app_data_buffer = ctx.ReadBuffer(0);
85 const auto image_data_buffer = ctx.ReadBuffer(1);
86
87 LOG_INFO(Service_Capture, 60 LOG_INFO(Service_Capture,
88 "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}", 61 "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}",
89 parameters.report_option, image_data_buffer.size(), 62 report_option, image_data_buffer.size(), aruid.pid);
90 parameters.applet_resource_user_id);
91 63
92 ApplicationAlbumEntry entry{};
93 ApplicationData app_data{};
94 std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData));
95 manager->FlipVerticallyOnWrite(false); 64 manager->FlipVerticallyOnWrite(false);
96 const auto result = 65 R_RETURN(manager->SaveScreenShot(*out_entry, attribute, report_option, *app_data_buffer,
97 manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, app_data, 66 image_data_buffer, aruid.pid));
98 image_data_buffer, parameters.applet_resource_user_id);
99
100 IPC::ResponseBuilder rb{ctx, 10};
101 rb.Push(result);
102 rb.PushRaw(entry);
103} 67}
104 68
105void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption report_option) { 69void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption report_option) {
@@ -112,6 +76,7 @@ void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption r
112 .orientation = Capture::AlbumImageOrientation::None, 76 .orientation = Capture::AlbumImageOrientation::None,
113 .unknown_1{}, 77 .unknown_1{},
114 .unknown_2{}, 78 .unknown_2{},
79 .pad163{},
115 }; 80 };
116 81
117 renderer.RequestScreenshot( 82 renderer.RequestScreenshot(
diff --git a/src/core/hle/service/caps/caps_su.h b/src/core/hle/service/caps/caps_su.h
index 21912e95f..4b4cbd09e 100644
--- a/src/core/hle/service/caps/caps_su.h
+++ b/src/core/hle/service/caps/caps_su.h
@@ -3,6 +3,8 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/caps/caps_types.h"
7#include "core/hle/service/cmif_types.h"
6#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
7 9
8namespace Core { 10namespace Core {
@@ -26,9 +28,19 @@ private:
26 static constexpr std::size_t screenshot_height = 720; 28 static constexpr std::size_t screenshot_height = 720;
27 static constexpr std::size_t bytes_per_pixel = 4; 29 static constexpr std::size_t bytes_per_pixel = 4;
28 30
29 void SetShimLibraryVersion(HLERequestContext& ctx); 31 Result SetShimLibraryVersion(ShimLibraryVersion library_version,
30 void SaveScreenShotEx0(HLERequestContext& ctx); 32 ClientAppletResourceUserId aruid);
31 void SaveScreenShotEx1(HLERequestContext& ctx); 33 Result SaveScreenShotEx0(
34 Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
35 AlbumReportOption report_option, ClientAppletResourceUserId aruid,
36 InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
37 image_data_buffer);
38 Result SaveScreenShotEx1(
39 Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
40 AlbumReportOption report_option, ClientAppletResourceUserId aruid,
41 const InLargeData<ApplicationData, BufferAttr_HipcMapAlias> app_data_buffer,
42 const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
43 image_data_buffer);
32 44
33 std::array<u8, screenshot_width * screenshot_height * bytes_per_pixel> image_data; 45 std::array<u8, screenshot_width * screenshot_height * bytes_per_pixel> image_data;
34 46
diff --git a/src/core/hle/service/caps/caps_types.h b/src/core/hle/service/caps/caps_types.h
index 589ac28d3..3deaaad5b 100644
--- a/src/core/hle/service/caps/caps_types.h
+++ b/src/core/hle/service/caps/caps_types.h
@@ -41,6 +41,10 @@ enum class ScreenShotDecoderFlag : u64 {
41 EnableBlockSmoothing = 1 << 1, 41 EnableBlockSmoothing = 1 << 1,
42}; 42};
43 43
44enum class ShimLibraryVersion : u64 {
45 Version1 = 1,
46};
47
44// This is nn::capsrv::AlbumFileDateTime 48// This is nn::capsrv::AlbumFileDateTime
45struct AlbumFileDateTime { 49struct AlbumFileDateTime {
46 s16 year{}; 50 s16 year{};
@@ -144,19 +148,23 @@ static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30,
144 "ApplicationAlbumFileEntry has incorrect size."); 148 "ApplicationAlbumFileEntry has incorrect size.");
145 149
146struct ApplicationData { 150struct ApplicationData {
147 std::array<u8, 0x400> data{}; 151 std::array<u8, 0x400> data;
148 u32 data_size{}; 152 u32 data_size;
149}; 153};
150static_assert(sizeof(ApplicationData) == 0x404, "ApplicationData is an invalid size"); 154static_assert(sizeof(ApplicationData) == 0x404, "ApplicationData is an invalid size");
155static_assert(std::is_trivial_v<ApplicationData>,
156 "ApplicationData type must be trivially copyable.");
151 157
152struct ScreenShotAttribute { 158struct ScreenShotAttribute {
153 u32 unknown_0{}; 159 u32 unknown_0;
154 AlbumImageOrientation orientation{}; 160 AlbumImageOrientation orientation;
155 u32 unknown_1{}; 161 u32 unknown_1;
156 u32 unknown_2{}; 162 u32 unknown_2;
157 INSERT_PADDING_BYTES(0x30); 163 INSERT_PADDING_BYTES_NOINIT(0x30);
158}; 164};
159static_assert(sizeof(ScreenShotAttribute) == 0x40, "ScreenShotAttribute is an invalid size"); 165static_assert(sizeof(ScreenShotAttribute) == 0x40, "ScreenShotAttribute is an invalid size");
166static_assert(std::is_trivial_v<ScreenShotAttribute>,
167 "ScreenShotAttribute type must be trivially copyable.");
160 168
161struct ScreenShotDecodeOption { 169struct ScreenShotDecodeOption {
162 ScreenShotDecoderFlag flags{}; 170 ScreenShotDecoderFlag flags{};
@@ -165,13 +173,15 @@ struct ScreenShotDecodeOption {
165static_assert(sizeof(ScreenShotDecodeOption) == 0x20, "ScreenShotDecodeOption is an invalid size"); 173static_assert(sizeof(ScreenShotDecodeOption) == 0x20, "ScreenShotDecodeOption is an invalid size");
166 174
167struct LoadAlbumScreenShotImageOutput { 175struct LoadAlbumScreenShotImageOutput {
168 s64 width{}; 176 s64 width;
169 s64 height{}; 177 s64 height;
170 ScreenShotAttribute attribute{}; 178 ScreenShotAttribute attribute;
171 INSERT_PADDING_BYTES(0x400); 179 INSERT_PADDING_BYTES_NOINIT(0x400);
172}; 180};
173static_assert(sizeof(LoadAlbumScreenShotImageOutput) == 0x450, 181static_assert(sizeof(LoadAlbumScreenShotImageOutput) == 0x450,
174 "LoadAlbumScreenShotImageOutput is an invalid size"); 182 "LoadAlbumScreenShotImageOutput is an invalid size");
183static_assert(std::is_trivial_v<LoadAlbumScreenShotImageOutput>,
184 "LoadAlbumScreenShotImageOutput type must be trivially copyable.");
175 185
176struct LoadAlbumScreenShotImageOutputForApplication { 186struct LoadAlbumScreenShotImageOutputForApplication {
177 s64 width{}; 187 s64 width{};
diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp
index b6b33fb2f..40d4d05fe 100644
--- a/src/core/hle/service/caps/caps_u.cpp
+++ b/src/core/hle/service/caps/caps_u.cpp
@@ -5,6 +5,7 @@
5#include "core/hle/service/caps/caps_manager.h" 5#include "core/hle/service/caps/caps_manager.h"
6#include "core/hle/service/caps/caps_types.h" 6#include "core/hle/service/caps/caps_types.h"
7#include "core/hle/service/caps/caps_u.h" 7#include "core/hle/service/caps/caps_u.h"
8#include "core/hle/service/cmif_serialization.h"
8#include "core/hle/service/ipc_helpers.h" 9#include "core/hle/service/ipc_helpers.h"
9 10
10namespace Service::Capture { 11namespace Service::Capture {
@@ -14,8 +15,8 @@ IAlbumApplicationService::IAlbumApplicationService(Core::System& system_,
14 : ServiceFramework{system_, "caps:u"}, manager{album_manager} { 15 : ServiceFramework{system_, "caps:u"}, manager{album_manager} {
15 // clang-format off 16 // clang-format off
16 static const FunctionInfo functions[] = { 17 static const FunctionInfo functions[] = {
17 {32, &IAlbumApplicationService::SetShimLibraryVersion, "SetShimLibraryVersion"}, 18 {32, C<&IAlbumApplicationService::SetShimLibraryVersion>, "SetShimLibraryVersion"},
18 {102, &IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated, "GetAlbumFileList0AafeAruidDeprecated"}, 19 {102, C<&IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated>, "GetAlbumFileList0AafeAruidDeprecated"},
19 {103, nullptr, "DeleteAlbumFileByAruid"}, 20 {103, nullptr, "DeleteAlbumFileByAruid"},
20 {104, nullptr, "GetAlbumFileSizeByAruid"}, 21 {104, nullptr, "GetAlbumFileSizeByAruid"},
21 {105, nullptr, "DeleteAlbumFileByAruidForDebug"}, 22 {105, nullptr, "DeleteAlbumFileByAruidForDebug"},
@@ -24,7 +25,7 @@ IAlbumApplicationService::IAlbumApplicationService(Core::System& system_,
24 {130, nullptr, "PrecheckToCreateContentsByAruid"}, 25 {130, nullptr, "PrecheckToCreateContentsByAruid"},
25 {140, nullptr, "GetAlbumFileList1AafeAruidDeprecated"}, 26 {140, nullptr, "GetAlbumFileList1AafeAruidDeprecated"},
26 {141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"}, 27 {141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"},
27 {142, &IAlbumApplicationService::GetAlbumFileList3AaeAruid, "GetAlbumFileList3AaeAruid"}, 28 {142, C<&IAlbumApplicationService::GetAlbumFileList3AaeAruid>, "GetAlbumFileList3AaeAruid"},
28 {143, nullptr, "GetAlbumFileList4AaeUidAruid"}, 29 {143, nullptr, "GetAlbumFileList4AaeUidAruid"},
29 {144, nullptr, "GetAllAlbumFileList3AaeAruid"}, 30 {144, nullptr, "GetAllAlbumFileList3AaeAruid"},
30 {60002, nullptr, "OpenAccessorSessionForApplication"}, 31 {60002, nullptr, "OpenAccessorSessionForApplication"},
@@ -36,101 +37,40 @@ IAlbumApplicationService::IAlbumApplicationService(Core::System& system_,
36 37
37IAlbumApplicationService::~IAlbumApplicationService() = default; 38IAlbumApplicationService::~IAlbumApplicationService() = default;
38 39
39void IAlbumApplicationService::SetShimLibraryVersion(HLERequestContext& ctx) { 40Result IAlbumApplicationService::SetShimLibraryVersion(ShimLibraryVersion library_version,
40 IPC::RequestParser rp{ctx}; 41 ClientAppletResourceUserId aruid) {
41 const auto library_version{rp.Pop<u64>()};
42 const auto applet_resource_user_id{rp.Pop<u64>()};
43
44 LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", 42 LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
45 library_version, applet_resource_user_id); 43 library_version, aruid.pid);
46 44 R_SUCCEED();
47 IPC::ResponseBuilder rb{ctx, 2};
48 rb.Push(ResultSuccess);
49} 45}
50 46
51void IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(HLERequestContext& ctx) { 47Result IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(
52 IPC::RequestParser rp{ctx}; 48 Out<u64> out_entries_count, ContentType content_type, s64 start_posix_time, s64 end_posix_time,
53 struct Parameters { 49 ClientAppletResourceUserId aruid,
54 ContentType content_type; 50 OutArray<ApplicationAlbumFileEntry, BufferAttr_HipcMapAlias> out_entries) {
55 INSERT_PADDING_BYTES(7);
56 s64 start_posix_time;
57 s64 end_posix_time;
58 u64 applet_resource_user_id;
59 };
60 static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
61
62 const auto parameters{rp.PopRaw<Parameters>()};
63
64 LOG_WARNING(Service_Capture, 51 LOG_WARNING(Service_Capture,
65 "(STUBBED) called. content_type={}, start_posix_time={}, end_posix_time={}, " 52 "(STUBBED) called. content_type={}, start_posix_time={}, end_posix_time={}, "
66 "applet_resource_user_id={}", 53 "applet_resource_user_id={}",
67 parameters.content_type, parameters.start_posix_time, parameters.end_posix_time, 54 content_type, start_posix_time, end_posix_time, aruid.pid);
68 parameters.applet_resource_user_id);
69
70 Result result = ResultSuccess;
71
72 if (result.IsSuccess()) {
73 result = manager->IsAlbumMounted(AlbumStorage::Sd);
74 }
75
76 std::vector<ApplicationAlbumFileEntry> entries;
77 if (result.IsSuccess()) {
78 result = manager->GetAlbumFileList(entries, parameters.content_type,
79 parameters.start_posix_time, parameters.end_posix_time,
80 parameters.applet_resource_user_id);
81 }
82 55
83 if (!entries.empty()) { 56 R_TRY(manager->IsAlbumMounted(AlbumStorage::Sd));
84 ctx.WriteBuffer(entries); 57 R_RETURN(manager->GetAlbumFileList(out_entries, *out_entries_count, content_type,
85 } 58 start_posix_time, end_posix_time, aruid.pid));
86
87 IPC::ResponseBuilder rb{ctx, 4};
88 rb.Push(result);
89 rb.Push<u64>(entries.size());
90} 59}
91 60
92void IAlbumApplicationService::GetAlbumFileList3AaeAruid(HLERequestContext& ctx) { 61Result IAlbumApplicationService::GetAlbumFileList3AaeAruid(
93 IPC::RequestParser rp{ctx}; 62 Out<u64> out_entries_count, ContentType content_type, AlbumFileDateTime start_date_time,
94 struct Parameters { 63 AlbumFileDateTime end_date_time, ClientAppletResourceUserId aruid,
95 ContentType content_type; 64 OutArray<ApplicationAlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
96 INSERT_PADDING_BYTES(1);
97 AlbumFileDateTime start_date_time;
98 AlbumFileDateTime end_date_time;
99 INSERT_PADDING_BYTES(6);
100 u64 applet_resource_user_id;
101 };
102 static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
103
104 const auto parameters{rp.PopRaw<Parameters>()};
105
106 LOG_WARNING(Service_Capture, 65 LOG_WARNING(Service_Capture,
107 "(STUBBED) called. content_type={}, start_date={}/{}/{}, " 66 "(STUBBED) called. content_type={}, start_date={}/{}/{}, "
108 "end_date={}/{}/{}, applet_resource_user_id={}", 67 "end_date={}/{}/{}, applet_resource_user_id={}",
109 parameters.content_type, parameters.start_date_time.year, 68 content_type, start_date_time.year, start_date_time.month, start_date_time.day,
110 parameters.start_date_time.month, parameters.start_date_time.day, 69 end_date_time.year, end_date_time.month, end_date_time.day, aruid.pid);
111 parameters.end_date_time.year, parameters.end_date_time.month,
112 parameters.end_date_time.day, parameters.applet_resource_user_id);
113
114 Result result = ResultSuccess;
115
116 if (result.IsSuccess()) {
117 result = manager->IsAlbumMounted(AlbumStorage::Sd);
118 }
119
120 std::vector<ApplicationAlbumEntry> entries;
121 if (result.IsSuccess()) {
122 result =
123 manager->GetAlbumFileList(entries, parameters.content_type, parameters.start_date_time,
124 parameters.end_date_time, parameters.applet_resource_user_id);
125 }
126
127 if (!entries.empty()) {
128 ctx.WriteBuffer(entries);
129 }
130 70
131 IPC::ResponseBuilder rb{ctx, 4}; 71 R_TRY(manager->IsAlbumMounted(AlbumStorage::Sd));
132 rb.Push(result); 72 R_RETURN(manager->GetAlbumFileList(out_entries, *out_entries_count, content_type,
133 rb.Push<u64>(entries.size()); 73 start_date_time, end_date_time, aruid.pid));
134} 74}
135 75
136} // namespace Service::Capture 76} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_u.h b/src/core/hle/service/caps/caps_u.h
index 9458c128e..023ee1fe7 100644
--- a/src/core/hle/service/caps/caps_u.h
+++ b/src/core/hle/service/caps/caps_u.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/cmif_types.h"
6#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
7 8
8namespace Core { 9namespace Core {
@@ -19,9 +20,18 @@ public:
19 ~IAlbumApplicationService() override; 20 ~IAlbumApplicationService() override;
20 21
21private: 22private:
22 void SetShimLibraryVersion(HLERequestContext& ctx); 23 Result SetShimLibraryVersion(ShimLibraryVersion library_version,
23 void GetAlbumFileList0AafeAruidDeprecated(HLERequestContext& ctx); 24 ClientAppletResourceUserId aruid);
24 void GetAlbumFileList3AaeAruid(HLERequestContext& ctx); 25
26 Result GetAlbumFileList0AafeAruidDeprecated(
27 Out<u64> out_entries_count, ContentType content_type, s64 start_posix_time,
28 s64 end_posix_time, ClientAppletResourceUserId aruid,
29 OutArray<ApplicationAlbumFileEntry, BufferAttr_HipcMapAlias> out_entries);
30
31 Result GetAlbumFileList3AaeAruid(
32 Out<u64> out_entries_count, ContentType content_type, AlbumFileDateTime start_date_time,
33 AlbumFileDateTime end_date_time, ClientAppletResourceUserId aruid,
34 OutArray<ApplicationAlbumEntry, BufferAttr_HipcMapAlias> out_entries);
25 35
26 std::shared_ptr<AlbumManager> manager = nullptr; 36 std::shared_ptr<AlbumManager> manager = nullptr;
27}; 37};