diff options
| author | 2023-10-17 23:05:44 -0600 | |
|---|---|---|
| committer | 2023-10-23 10:18:22 -0600 | |
| commit | 897b411ae76a817421453120ca0d0812e3de233f (patch) | |
| tree | c4d69fd35790e21605c6382b29107186e5e2a6a1 /src/core/hle/service/caps | |
| parent | externals: stb: Add image write (diff) | |
| download | yuzu-897b411ae76a817421453120ca0d0812e3de233f.tar.gz yuzu-897b411ae76a817421453120ca0d0812e3de233f.tar.xz yuzu-897b411ae76a817421453120ca0d0812e3de233f.zip | |
service: caps: Implement SaveScreenShotEx0 and variants
Diffstat (limited to 'src/core/hle/service/caps')
| -rw-r--r-- | src/core/hle/service/caps/caps.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_manager.cpp | 83 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_manager.h | 11 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_ss.cpp | 75 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_ss.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_su.cpp | 69 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_su.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/caps/caps_types.h | 2 |
8 files changed, 250 insertions, 13 deletions
diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp index 31dd98140..cd1dfe993 100644 --- a/src/core/hle/service/caps/caps.cpp +++ b/src/core/hle/service/caps/caps.cpp | |||
| @@ -25,11 +25,12 @@ void LoopProcess(Core::System& system) { | |||
| 25 | server_manager->RegisterNamedService( | 25 | server_manager->RegisterNamedService( |
| 26 | "caps:u", std::make_shared<IAlbumApplicationService>(system, album_manager)); | 26 | "caps:u", std::make_shared<IAlbumApplicationService>(system, album_manager)); |
| 27 | 27 | ||
| 28 | server_manager->RegisterNamedService("caps:ss", std::make_shared<IScreenShotService>(system)); | 28 | server_manager->RegisterNamedService( |
| 29 | "caps:ss", std::make_shared<IScreenShotService>(system, album_manager)); | ||
| 29 | server_manager->RegisterNamedService("caps:sc", | 30 | server_manager->RegisterNamedService("caps:sc", |
| 30 | std::make_shared<IScreenShotControlService>(system)); | 31 | std::make_shared<IScreenShotControlService>(system)); |
| 31 | server_manager->RegisterNamedService("caps:su", | 32 | server_manager->RegisterNamedService( |
| 32 | std::make_shared<IScreenShotApplicationService>(system)); | 33 | "caps:su", std::make_shared<IScreenShotApplicationService>(system, album_manager)); |
| 33 | 34 | ||
| 34 | ServerManager::RunServer(std::move(server_manager)); | 35 | ServerManager::RunServer(std::move(server_manager)); |
| 35 | } | 36 | } |
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp index 2b4e3f076..9c9454b99 100644 --- a/src/core/hle/service/caps/caps_manager.cpp +++ b/src/core/hle/service/caps/caps_manager.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <sstream> | 4 | #include <sstream> |
| 5 | #include <stb_image.h> | 5 | #include <stb_image.h> |
| 6 | #include <stb_image_resize.h> | 6 | #include <stb_image_resize.h> |
| 7 | #include <stb_image_write.h> | ||
| 7 | 8 | ||
| 8 | #include "common/fs/file.h" | 9 | #include "common/fs/file.h" |
| 9 | #include "common/fs/path_util.h" | 10 | #include "common/fs/path_util.h" |
| @@ -227,6 +228,49 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail( | |||
| 227 | +static_cast<int>(out_image_output.height), decoder_options.flags); | 228 | +static_cast<int>(out_image_output.height), decoder_options.flags); |
| 228 | } | 229 | } |
| 229 | 230 | ||
| 231 | Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, | ||
| 232 | const ScreenShotAttribute& attribute, | ||
| 233 | std::span<const u8> image_data, u64 aruid) { | ||
| 234 | return SaveScreenShot(out_entry, attribute, {}, image_data, aruid); | ||
| 235 | } | ||
| 236 | |||
| 237 | Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, | ||
| 238 | const ScreenShotAttribute& attribute, | ||
| 239 | const ApplicationData& app_data, std::span<const u8> image_data, | ||
| 240 | u64 aruid) { | ||
| 241 | const u64 title_id = system.GetApplicationProcessProgramID(); | ||
| 242 | const auto& user_clock = system.GetTimeManager().GetStandardUserSystemClockCore(); | ||
| 243 | |||
| 244 | s64 posix_time{}; | ||
| 245 | Result result = user_clock.GetCurrentTime(system, posix_time); | ||
| 246 | |||
| 247 | if (result.IsError()) { | ||
| 248 | return result; | ||
| 249 | } | ||
| 250 | |||
| 251 | const auto date = ConvertToAlbumDateTime(posix_time); | ||
| 252 | |||
| 253 | return SaveImage(out_entry, image_data, title_id, date); | ||
| 254 | } | ||
| 255 | |||
| 256 | Result AlbumManager::SaveEditedScreenShot(ApplicationAlbumEntry& out_entry, | ||
| 257 | const ScreenShotAttribute& attribute, | ||
| 258 | const AlbumFileId& file_id, | ||
| 259 | std::span<const u8> image_data) { | ||
| 260 | const auto& user_clock = system.GetTimeManager().GetStandardUserSystemClockCore(); | ||
| 261 | |||
| 262 | s64 posix_time{}; | ||
| 263 | Result result = user_clock.GetCurrentTime(system, posix_time); | ||
| 264 | |||
| 265 | if (result.IsError()) { | ||
| 266 | return result; | ||
| 267 | } | ||
| 268 | |||
| 269 | const auto date = ConvertToAlbumDateTime(posix_time); | ||
| 270 | |||
| 271 | return SaveImage(out_entry, image_data, file_id.application_id, date); | ||
| 272 | } | ||
| 273 | |||
| 230 | Result AlbumManager::GetFile(std::filesystem::path& out_path, const AlbumFileId& file_id) const { | 274 | Result AlbumManager::GetFile(std::filesystem::path& out_path, const AlbumFileId& file_id) const { |
| 231 | const auto file = album_files.find(file_id); | 275 | const auto file = album_files.find(file_id); |
| 232 | 276 | ||
| @@ -365,6 +409,45 @@ Result AlbumManager::LoadImage(std::span<u8> out_image, const std::filesystem::p | |||
| 365 | return ResultSuccess; | 409 | return ResultSuccess; |
| 366 | } | 410 | } |
| 367 | 411 | ||
| 412 | Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span<const u8> image, | ||
| 413 | u64 title_id, const AlbumFileDateTime& date) const { | ||
| 414 | const auto screenshot_path = | ||
| 415 | Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir); | ||
| 416 | const std::string formatted_date = | ||
| 417 | fmt::format("{:04}-{:02}-{:02}_{:02}-{:02}-{:02}-{:03}", date.year, date.month, date.day, | ||
| 418 | date.hour, date.minute, date.second, 0); | ||
| 419 | const std::string file_path = | ||
| 420 | fmt::format("{}/{:016x}_{}.png", screenshot_path, title_id, formatted_date); | ||
| 421 | |||
| 422 | const Common::FS::IOFile db_file{file_path, Common::FS::FileAccessMode::Write, | ||
| 423 | Common::FS::FileType::BinaryFile}; | ||
| 424 | |||
| 425 | s32 len; | ||
| 426 | const u8* png = stbi_write_png_to_mem(image.data(), 0, 1280, 720, STBI_rgb_alpha, &len); | ||
| 427 | |||
| 428 | if (!png) { | ||
| 429 | return ResultFileCountLimit; | ||
| 430 | } | ||
| 431 | |||
| 432 | std::vector<u8> png_image(len); | ||
| 433 | std::memcpy(png_image.data(), png, len); | ||
| 434 | |||
| 435 | if (db_file.Write(png_image) != png_image.size()) { | ||
| 436 | return ResultFileCountLimit; | ||
| 437 | } | ||
| 438 | |||
| 439 | out_entry = { | ||
| 440 | .size = png_image.size(), | ||
| 441 | .hash = {}, | ||
| 442 | .datetime = date, | ||
| 443 | .storage = AlbumStorage::Sd, | ||
| 444 | .content = ContentType::Screenshot, | ||
| 445 | .unknown = 1, | ||
| 446 | }; | ||
| 447 | |||
| 448 | return ResultSuccess; | ||
| 449 | } | ||
| 450 | |||
| 368 | AlbumFileDateTime AlbumManager::ConvertToAlbumDateTime(u64 posix_time) const { | 451 | AlbumFileDateTime AlbumManager::ConvertToAlbumDateTime(u64 posix_time) const { |
| 369 | Time::TimeZone::CalendarInfo calendar_date{}; | 452 | Time::TimeZone::CalendarInfo calendar_date{}; |
| 370 | const auto& time_zone_manager = | 453 | const auto& time_zone_manager = |
diff --git a/src/core/hle/service/caps/caps_manager.h b/src/core/hle/service/caps/caps_manager.h index f65eb12c1..44d85117f 100644 --- a/src/core/hle/service/caps/caps_manager.h +++ b/src/core/hle/service/caps/caps_manager.h | |||
| @@ -58,6 +58,15 @@ public: | |||
| 58 | std::vector<u8>& out_image, const AlbumFileId& file_id, | 58 | std::vector<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, | ||
| 62 | std::span<const u8> image_data, u64 aruid); | ||
| 63 | Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute, | ||
| 64 | const ApplicationData& app_data, std::span<const u8> image_data, | ||
| 65 | u64 aruid); | ||
| 66 | Result SaveEditedScreenShot(ApplicationAlbumEntry& out_entry, | ||
| 67 | const ScreenShotAttribute& attribute, const AlbumFileId& file_id, | ||
| 68 | std::span<const u8> image_data); | ||
| 69 | |||
| 61 | private: | 70 | private: |
| 62 | static constexpr std::size_t NandAlbumFileLimit = 1000; | 71 | static constexpr std::size_t NandAlbumFileLimit = 1000; |
| 63 | static constexpr std::size_t SdAlbumFileLimit = 10000; | 72 | static constexpr std::size_t SdAlbumFileLimit = 10000; |
| @@ -67,6 +76,8 @@ private: | |||
| 67 | Result GetAlbumEntry(AlbumEntry& out_entry, const std::filesystem::path& path) const; | 76 | Result GetAlbumEntry(AlbumEntry& out_entry, const std::filesystem::path& path) const; |
| 68 | Result LoadImage(std::span<u8> out_image, const std::filesystem::path& path, int width, | 77 | Result LoadImage(std::span<u8> out_image, const std::filesystem::path& path, int width, |
| 69 | int height, ScreenShotDecoderFlag flag) const; | 78 | int height, ScreenShotDecoderFlag flag) const; |
| 79 | Result SaveImage(ApplicationAlbumEntry& out_entry, std::span<const u8> image, u64 title_id, | ||
| 80 | const AlbumFileDateTime& date) const; | ||
| 70 | 81 | ||
| 71 | AlbumFileDateTime ConvertToAlbumDateTime(u64 posix_time) const; | 82 | AlbumFileDateTime ConvertToAlbumDateTime(u64 posix_time) const; |
| 72 | 83 | ||
diff --git a/src/core/hle/service/caps/caps_ss.cpp b/src/core/hle/service/caps/caps_ss.cpp index d0d1b5425..1ba2b7972 100644 --- a/src/core/hle/service/caps/caps_ss.cpp +++ b/src/core/hle/service/caps/caps_ss.cpp | |||
| @@ -1,19 +1,25 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/logging/log.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 | |||
| 4 | #include "core/hle/service/caps/caps_ss.h" | 9 | #include "core/hle/service/caps/caps_ss.h" |
| 5 | 10 | ||
| 6 | namespace Service::Capture { | 11 | namespace Service::Capture { |
| 7 | 12 | ||
| 8 | IScreenShotService::IScreenShotService(Core::System& system_) | 13 | IScreenShotService::IScreenShotService(Core::System& system_, |
| 9 | : ServiceFramework{system_, "caps:ss"} { | 14 | std::shared_ptr<AlbumManager> album_manager) |
| 15 | : ServiceFramework{system_, "caps:ss"}, manager{album_manager} { | ||
| 10 | // clang-format off | 16 | // clang-format off |
| 11 | static const FunctionInfo functions[] = { | 17 | static const FunctionInfo functions[] = { |
| 12 | {201, nullptr, "SaveScreenShot"}, | 18 | {201, nullptr, "SaveScreenShot"}, |
| 13 | {202, nullptr, "SaveEditedScreenShot"}, | 19 | {202, nullptr, "SaveEditedScreenShot"}, |
| 14 | {203, nullptr, "SaveScreenShotEx0"}, | 20 | {203, &IScreenShotService::SaveScreenShotEx0, "SaveScreenShotEx0"}, |
| 15 | {204, nullptr, "SaveEditedScreenShotEx0"}, | 21 | {204, nullptr, "SaveEditedScreenShotEx0"}, |
| 16 | {206, nullptr, "Unknown206"}, | 22 | {206, &IScreenShotService::SaveEditedScreenShotEx1, "SaveEditedScreenShotEx1"}, |
| 17 | {208, nullptr, "SaveScreenShotOfMovieEx1"}, | 23 | {208, nullptr, "SaveScreenShotOfMovieEx1"}, |
| 18 | {1000, nullptr, "Unknown1000"}, | 24 | {1000, nullptr, "Unknown1000"}, |
| 19 | }; | 25 | }; |
| @@ -24,4 +30,65 @@ IScreenShotService::IScreenShotService(Core::System& system_) | |||
| 24 | 30 | ||
| 25 | IScreenShotService::~IScreenShotService() = default; | 31 | IScreenShotService::~IScreenShotService() = default; |
| 26 | 32 | ||
| 33 | void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) { | ||
| 34 | IPC::RequestParser rp{ctx}; | ||
| 35 | struct Parameters { | ||
| 36 | ScreenShotAttribute attribute{}; | ||
| 37 | u32 report_option{}; | ||
| 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, | ||
| 47 | "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}", | ||
| 48 | parameters.report_option, image_data_buffer.size(), | ||
| 49 | parameters.applet_resource_user_id); | ||
| 50 | |||
| 51 | ApplicationAlbumEntry entry{}; | ||
| 52 | const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer, | ||
| 53 | parameters.applet_resource_user_id); | ||
| 54 | |||
| 55 | IPC::ResponseBuilder rb{ctx, 10}; | ||
| 56 | rb.Push(result); | ||
| 57 | rb.PushRaw(entry); | ||
| 58 | } | ||
| 59 | void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) { | ||
| 60 | IPC::RequestParser rp{ctx}; | ||
| 61 | struct Parameters { | ||
| 62 | ScreenShotAttribute attribute; | ||
| 63 | u64 width; | ||
| 64 | u64 height; | ||
| 65 | u64 thumbnail_width; | ||
| 66 | u64 thumbnail_height; | ||
| 67 | AlbumFileId file_id; | ||
| 68 | }; | ||
| 69 | static_assert(sizeof(Parameters) == 0x78, "Parameters has incorrect size."); | ||
| 70 | |||
| 71 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 72 | const auto application_data_buffer = ctx.ReadBuffer(0); | ||
| 73 | const auto image_data_buffer = ctx.ReadBuffer(1); | ||
| 74 | const auto thumbnail_image_data_buffer = ctx.ReadBuffer(2); | ||
| 75 | |||
| 76 | LOG_INFO(Service_Capture, | ||
| 77 | "called, width={}, height={}, thumbnail_width={}, thumbnail_height={}, " | ||
| 78 | "application_id={:016x}, storage={}, type={}, app_data_buffer_size={}, " | ||
| 79 | "image_data_buffer_size={}, thumbnail_image_buffer_size={}", | ||
| 80 | parameters.width, parameters.height, parameters.thumbnail_width, | ||
| 81 | parameters.thumbnail_height, parameters.file_id.application_id, | ||
| 82 | parameters.file_id.storage, parameters.file_id.type, application_data_buffer.size(), | ||
| 83 | image_data_buffer.size(), thumbnail_image_data_buffer.size()); | ||
| 84 | |||
| 85 | ApplicationAlbumEntry entry{}; | ||
| 86 | const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute, | ||
| 87 | parameters.file_id, image_data_buffer); | ||
| 88 | |||
| 89 | IPC::ResponseBuilder rb{ctx, 10}; | ||
| 90 | rb.Push(result); | ||
| 91 | rb.PushRaw(entry); | ||
| 92 | } | ||
| 93 | |||
| 27 | } // namespace Service::Capture | 94 | } // namespace Service::Capture |
diff --git a/src/core/hle/service/caps/caps_ss.h b/src/core/hle/service/caps/caps_ss.h index 381e44fd4..a7e9972ab 100644 --- a/src/core/hle/service/caps/caps_ss.h +++ b/src/core/hle/service/caps/caps_ss.h | |||
| @@ -13,8 +13,14 @@ namespace Service::Capture { | |||
| 13 | 13 | ||
| 14 | class IScreenShotService final : public ServiceFramework<IScreenShotService> { | 14 | class IScreenShotService final : public ServiceFramework<IScreenShotService> { |
| 15 | public: | 15 | public: |
| 16 | explicit IScreenShotService(Core::System& system_); | 16 | explicit IScreenShotService(Core::System& system_, std::shared_ptr<AlbumManager> album_manager); |
| 17 | ~IScreenShotService() override; | 17 | ~IScreenShotService() override; |
| 18 | |||
| 19 | private: | ||
| 20 | void SaveScreenShotEx0(HLERequestContext& ctx); | ||
| 21 | void SaveEditedScreenShotEx1(HLERequestContext& ctx); | ||
| 22 | |||
| 23 | std::shared_ptr<AlbumManager> manager; | ||
| 18 | }; | 24 | }; |
| 19 | 25 | ||
| 20 | } // namespace Service::Capture | 26 | } // namespace Service::Capture |
diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp index cad173dc7..e85625ee4 100644 --- a/src/core/hle/service/caps/caps_su.cpp +++ b/src/core/hle/service/caps/caps_su.cpp | |||
| @@ -2,19 +2,22 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 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_su.h" | 6 | #include "core/hle/service/caps/caps_su.h" |
| 7 | #include "core/hle/service/caps/caps_types.h" | ||
| 6 | #include "core/hle/service/ipc_helpers.h" | 8 | #include "core/hle/service/ipc_helpers.h" |
| 7 | 9 | ||
| 8 | namespace Service::Capture { | 10 | namespace Service::Capture { |
| 9 | 11 | ||
| 10 | IScreenShotApplicationService::IScreenShotApplicationService(Core::System& system_) | 12 | IScreenShotApplicationService::IScreenShotApplicationService( |
| 11 | : ServiceFramework{system_, "caps:su"} { | 13 | Core::System& system_, std::shared_ptr<AlbumManager> album_manager) |
| 14 | : ServiceFramework{system_, "caps:su"}, manager{album_manager} { | ||
| 12 | // clang-format off | 15 | // clang-format off |
| 13 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 14 | {32, &IScreenShotApplicationService::SetShimLibraryVersion, "SetShimLibraryVersion"}, | 17 | {32, &IScreenShotApplicationService::SetShimLibraryVersion, "SetShimLibraryVersion"}, |
| 15 | {201, nullptr, "SaveScreenShot"}, | 18 | {201, nullptr, "SaveScreenShot"}, |
| 16 | {203, nullptr, "SaveScreenShotEx0"}, | 19 | {203, &IScreenShotApplicationService::SaveScreenShotEx0, "SaveScreenShotEx0"}, |
| 17 | {205, nullptr, "SaveScreenShotEx1"}, | 20 | {205, &IScreenShotApplicationService::SaveScreenShotEx1, "SaveScreenShotEx1"}, |
| 18 | {210, nullptr, "SaveScreenShotEx2"}, | 21 | {210, nullptr, "SaveScreenShotEx2"}, |
| 19 | }; | 22 | }; |
| 20 | // clang-format on | 23 | // clang-format on |
| @@ -36,4 +39,62 @@ void IScreenShotApplicationService::SetShimLibraryVersion(HLERequestContext& ctx | |||
| 36 | rb.Push(ResultSuccess); | 39 | rb.Push(ResultSuccess); |
| 37 | } | 40 | } |
| 38 | 41 | ||
| 42 | void IScreenShotApplicationService::SaveScreenShotEx0(HLERequestContext& ctx) { | ||
| 43 | IPC::RequestParser rp{ctx}; | ||
| 44 | struct Parameters { | ||
| 45 | ScreenShotAttribute attribute{}; | ||
| 46 | AlbumReportOption report_option{}; | ||
| 47 | INSERT_PADDING_BYTES(0x4); | ||
| 48 | u64 applet_resource_user_id{}; | ||
| 49 | }; | ||
| 50 | static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size."); | ||
| 51 | |||
| 52 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 53 | const auto image_data_buffer = ctx.ReadBuffer(); | ||
| 54 | |||
| 55 | LOG_INFO(Service_Capture, | ||
| 56 | "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}", | ||
| 57 | parameters.report_option, image_data_buffer.size(), | ||
| 58 | parameters.applet_resource_user_id); | ||
| 59 | |||
| 60 | ApplicationAlbumEntry entry{}; | ||
| 61 | const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer, | ||
| 62 | parameters.applet_resource_user_id); | ||
| 63 | |||
| 64 | IPC::ResponseBuilder rb{ctx, 10}; | ||
| 65 | rb.Push(result); | ||
| 66 | rb.PushRaw(entry); | ||
| 67 | } | ||
| 68 | |||
| 69 | void IScreenShotApplicationService::SaveScreenShotEx1(HLERequestContext& ctx) { | ||
| 70 | IPC::RequestParser rp{ctx}; | ||
| 71 | struct Parameters { | ||
| 72 | ScreenShotAttribute attribute{}; | ||
| 73 | AlbumReportOption report_option{}; | ||
| 74 | INSERT_PADDING_BYTES(0x4); | ||
| 75 | u64 applet_resource_user_id{}; | ||
| 76 | }; | ||
| 77 | static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size."); | ||
| 78 | |||
| 79 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 80 | const auto app_data_buffer = ctx.ReadBuffer(0); | ||
| 81 | const auto image_data_buffer = ctx.ReadBuffer(1); | ||
| 82 | |||
| 83 | LOG_INFO(Service_Capture, | ||
| 84 | "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}", | ||
| 85 | parameters.report_option, image_data_buffer.size(), | ||
| 86 | parameters.applet_resource_user_id); | ||
| 87 | |||
| 88 | ApplicationAlbumEntry entry{}; | ||
| 89 | ApplicationData app_data{}; | ||
| 90 | std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData)); | ||
| 91 | const auto result = | ||
| 92 | manager->SaveScreenShot(entry, parameters.attribute, app_data, image_data_buffer, | ||
| 93 | parameters.applet_resource_user_id); | ||
| 94 | |||
| 95 | IPC::ResponseBuilder rb{ctx, 10}; | ||
| 96 | rb.Push(result); | ||
| 97 | rb.PushRaw(entry); | ||
| 98 | } | ||
| 99 | |||
| 39 | } // namespace Service::Capture | 100 | } // namespace Service::Capture |
diff --git a/src/core/hle/service/caps/caps_su.h b/src/core/hle/service/caps/caps_su.h index 647e3059d..89e71f506 100644 --- a/src/core/hle/service/caps/caps_su.h +++ b/src/core/hle/service/caps/caps_su.h | |||
| @@ -10,14 +10,20 @@ class System; | |||
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | namespace Service::Capture { | 12 | namespace Service::Capture { |
| 13 | class AlbumManager; | ||
| 13 | 14 | ||
| 14 | class IScreenShotApplicationService final : public ServiceFramework<IScreenShotApplicationService> { | 15 | class IScreenShotApplicationService final : public ServiceFramework<IScreenShotApplicationService> { |
| 15 | public: | 16 | public: |
| 16 | explicit IScreenShotApplicationService(Core::System& system_); | 17 | explicit IScreenShotApplicationService(Core::System& system_, |
| 18 | std::shared_ptr<AlbumManager> album_manager); | ||
| 17 | ~IScreenShotApplicationService() override; | 19 | ~IScreenShotApplicationService() override; |
| 18 | 20 | ||
| 19 | private: | 21 | private: |
| 20 | void SetShimLibraryVersion(HLERequestContext& ctx); | 22 | void SetShimLibraryVersion(HLERequestContext& ctx); |
| 23 | void SaveScreenShotEx0(HLERequestContext& ctx); | ||
| 24 | void SaveScreenShotEx1(HLERequestContext& ctx); | ||
| 25 | |||
| 26 | std::shared_ptr<AlbumManager> manager; | ||
| 21 | }; | 27 | }; |
| 22 | 28 | ||
| 23 | } // namespace Service::Capture | 29 | } // namespace Service::Capture |
diff --git a/src/core/hle/service/caps/caps_types.h b/src/core/hle/service/caps/caps_types.h index 7fd357954..589ac28d3 100644 --- a/src/core/hle/service/caps/caps_types.h +++ b/src/core/hle/service/caps/caps_types.h | |||
| @@ -20,6 +20,8 @@ enum class AlbumImageOrientation { | |||
| 20 | enum class AlbumReportOption : s32 { | 20 | enum class AlbumReportOption : s32 { |
| 21 | Disable, | 21 | Disable, |
| 22 | Enable, | 22 | Enable, |
| 23 | Unknown2, | ||
| 24 | Unknown3, | ||
| 23 | }; | 25 | }; |
| 24 | 26 | ||
| 25 | enum class ContentType : u8 { | 27 | enum class ContentType : u8 { |