summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/am.cpp13
-rw-r--r--src/core/hle/service/caps/caps_manager.cpp16
-rw-r--r--src/core/hle/service/caps/caps_manager.h9
-rw-r--r--src/core/hle/service/caps/caps_ss.cpp10
-rw-r--r--src/core/hle/service/caps/caps_su.cpp42
-rw-r--r--src/core/hle/service/caps/caps_su.h9
6 files changed, 82 insertions, 17 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index ff067c8d9..242ea6665 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -31,6 +31,7 @@
31#include "core/hle/service/apm/apm_controller.h" 31#include "core/hle/service/apm/apm_controller.h"
32#include "core/hle/service/apm/apm_interface.h" 32#include "core/hle/service/apm/apm_interface.h"
33#include "core/hle/service/bcat/backend/backend.h" 33#include "core/hle/service/bcat/backend/backend.h"
34#include "core/hle/service/caps/caps_su.h"
34#include "core/hle/service/caps/caps_types.h" 35#include "core/hle/service/caps/caps_types.h"
35#include "core/hle/service/filesystem/filesystem.h" 36#include "core/hle/service/filesystem/filesystem.h"
36#include "core/hle/service/ipc_helpers.h" 37#include "core/hle/service/ipc_helpers.h"
@@ -702,9 +703,17 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& c
702void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) { 703void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) {
703 IPC::RequestParser rp{ctx}; 704 IPC::RequestParser rp{ctx};
704 705
705 const auto album_report_option = rp.PopEnum<Capture::AlbumReportOption>(); 706 const auto report_option = rp.PopEnum<Capture::AlbumReportOption>();
706 707
707 LOG_WARNING(Service_AM, "(STUBBED) called. album_report_option={}", album_report_option); 708 LOG_INFO(Service_AM, "called, report_option={}", report_option);
709
710 const auto screenshot_service =
711 system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>(
712 "caps:su");
713
714 if (screenshot_service) {
715 screenshot_service->CaptureAndSaveScreenshot(report_option);
716 }
708 717
709 IPC::ResponseBuilder rb{ctx, 2}; 718 IPC::ResponseBuilder rb{ctx, 2};
710 rb.Push(ResultSuccess); 719 rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp
index 7d733eb54..96b225d5f 100644
--- a/src/core/hle/service/caps/caps_manager.cpp
+++ b/src/core/hle/service/caps/caps_manager.cpp
@@ -228,12 +228,14 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(
228 228
229Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, 229Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
230 const ScreenShotAttribute& attribute, 230 const ScreenShotAttribute& attribute,
231 std::span<const u8> image_data, u64 aruid) { 231 AlbumReportOption report_option, std::span<const u8> image_data,
232 return SaveScreenShot(out_entry, attribute, {}, image_data, aruid); 232 u64 aruid) {
233 return SaveScreenShot(out_entry, attribute, report_option, {}, image_data, aruid);
233} 234}
234 235
235Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, 236Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
236 const ScreenShotAttribute& attribute, 237 const ScreenShotAttribute& attribute,
238 AlbumReportOption report_option,
237 const ApplicationData& app_data, std::span<const u8> image_data, 239 const ApplicationData& app_data, std::span<const u8> image_data,
238 u64 aruid) { 240 u64 aruid) {
239 const u64 title_id = system.GetApplicationProcessProgramID(); 241 const u64 title_id = system.GetApplicationProcessProgramID();
@@ -407,10 +409,14 @@ Result AlbumManager::LoadImage(std::span<u8> out_image, const std::filesystem::p
407 return ResultSuccess; 409 return ResultSuccess;
408} 410}
409 411
410static void PNGToMemory(void* context, void* png, int len) { 412void AlbumManager::FlipVerticallyOnWrite(bool flip) {
413 stbi_flip_vertically_on_write(flip);
414}
415
416static void PNGToMemory(void* context, void* data, int len) {
411 std::vector<u8>* png_image = static_cast<std::vector<u8>*>(context); 417 std::vector<u8>* png_image = static_cast<std::vector<u8>*>(context);
412 png_image->reserve(len); 418 unsigned char* png = static_cast<unsigned char*>(data);
413 std::memcpy(png_image->data(), png, len); 419 png_image->insert(png_image->end(), png, png + len);
414} 420}
415 421
416Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span<const u8> image, 422Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span<const u8> image,
diff --git a/src/core/hle/service/caps/caps_manager.h b/src/core/hle/service/caps/caps_manager.h
index 44d85117f..e20c70c7b 100644
--- a/src/core/hle/service/caps/caps_manager.h
+++ b/src/core/hle/service/caps/caps_manager.h
@@ -59,14 +59,17 @@ public:
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,
62 std::span<const u8> image_data, u64 aruid); 62 AlbumReportOption report_option, std::span<const u8> image_data,
63 Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
64 const ApplicationData& app_data, std::span<const u8> image_data,
65 u64 aruid); 63 u64 aruid);
64 Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
65 AlbumReportOption report_option, const ApplicationData& app_data,
66 std::span<const u8> image_data, u64 aruid);
66 Result SaveEditedScreenShot(ApplicationAlbumEntry& out_entry, 67 Result SaveEditedScreenShot(ApplicationAlbumEntry& out_entry,
67 const ScreenShotAttribute& attribute, const AlbumFileId& file_id, 68 const ScreenShotAttribute& attribute, const AlbumFileId& file_id,
68 std::span<const u8> image_data); 69 std::span<const u8> image_data);
69 70
71 void FlipVerticallyOnWrite(bool flip);
72
70private: 73private:
71 static constexpr std::size_t NandAlbumFileLimit = 1000; 74 static constexpr std::size_t NandAlbumFileLimit = 1000;
72 static constexpr std::size_t SdAlbumFileLimit = 10000; 75 static constexpr std::size_t SdAlbumFileLimit = 10000;
diff --git a/src/core/hle/service/caps/caps_ss.cpp b/src/core/hle/service/caps/caps_ss.cpp
index 1ba2b7972..eab023568 100644
--- a/src/core/hle/service/caps/caps_ss.cpp
+++ b/src/core/hle/service/caps/caps_ss.cpp
@@ -34,7 +34,7 @@ void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) {
34 IPC::RequestParser rp{ctx}; 34 IPC::RequestParser rp{ctx};
35 struct Parameters { 35 struct Parameters {
36 ScreenShotAttribute attribute{}; 36 ScreenShotAttribute attribute{};
37 u32 report_option{}; 37 AlbumReportOption report_option{};
38 INSERT_PADDING_BYTES(0x4); 38 INSERT_PADDING_BYTES(0x4);
39 u64 applet_resource_user_id{}; 39 u64 applet_resource_user_id{};
40 }; 40 };
@@ -49,13 +49,16 @@ void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) {
49 parameters.applet_resource_user_id); 49 parameters.applet_resource_user_id);
50 50
51 ApplicationAlbumEntry entry{}; 51 ApplicationAlbumEntry entry{};
52 const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer, 52 manager->FlipVerticallyOnWrite(false);
53 parameters.applet_resource_user_id); 53 const auto result =
54 manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option,
55 image_data_buffer, parameters.applet_resource_user_id);
54 56
55 IPC::ResponseBuilder rb{ctx, 10}; 57 IPC::ResponseBuilder rb{ctx, 10};
56 rb.Push(result); 58 rb.Push(result);
57 rb.PushRaw(entry); 59 rb.PushRaw(entry);
58} 60}
61
59void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) { 62void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) {
60 IPC::RequestParser rp{ctx}; 63 IPC::RequestParser rp{ctx};
61 struct Parameters { 64 struct Parameters {
@@ -83,6 +86,7 @@ void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) {
83 image_data_buffer.size(), thumbnail_image_data_buffer.size()); 86 image_data_buffer.size(), thumbnail_image_data_buffer.size());
84 87
85 ApplicationAlbumEntry entry{}; 88 ApplicationAlbumEntry entry{};
89 manager->FlipVerticallyOnWrite(false);
86 const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute, 90 const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute,
87 parameters.file_id, image_data_buffer); 91 parameters.file_id, image_data_buffer);
88 92
diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp
index e85625ee4..296b07b00 100644
--- a/src/core/hle/service/caps/caps_su.cpp
+++ b/src/core/hle/service/caps/caps_su.cpp
@@ -2,10 +2,12 @@
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/core.h"
5#include "core/hle/service/caps/caps_manager.h" 6#include "core/hle/service/caps/caps_manager.h"
6#include "core/hle/service/caps/caps_su.h" 7#include "core/hle/service/caps/caps_su.h"
7#include "core/hle/service/caps/caps_types.h" 8#include "core/hle/service/caps/caps_types.h"
8#include "core/hle/service/ipc_helpers.h" 9#include "core/hle/service/ipc_helpers.h"
10#include "video_core/renderer_base.h"
9 11
10namespace Service::Capture { 12namespace Service::Capture {
11 13
@@ -58,8 +60,10 @@ void IScreenShotApplicationService::SaveScreenShotEx0(HLERequestContext& ctx) {
58 parameters.applet_resource_user_id); 60 parameters.applet_resource_user_id);
59 61
60 ApplicationAlbumEntry entry{}; 62 ApplicationAlbumEntry entry{};
61 const auto result = manager->SaveScreenShot(entry, parameters.attribute, image_data_buffer, 63 manager->FlipVerticallyOnWrite(false);
62 parameters.applet_resource_user_id); 64 const auto result =
65 manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option,
66 image_data_buffer, parameters.applet_resource_user_id);
63 67
64 IPC::ResponseBuilder rb{ctx, 10}; 68 IPC::ResponseBuilder rb{ctx, 10};
65 rb.Push(result); 69 rb.Push(result);
@@ -88,13 +92,43 @@ void IScreenShotApplicationService::SaveScreenShotEx1(HLERequestContext& ctx) {
88 ApplicationAlbumEntry entry{}; 92 ApplicationAlbumEntry entry{};
89 ApplicationData app_data{}; 93 ApplicationData app_data{};
90 std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData)); 94 std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData));
95 manager->FlipVerticallyOnWrite(false);
91 const auto result = 96 const auto result =
92 manager->SaveScreenShot(entry, parameters.attribute, app_data, image_data_buffer, 97 manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, app_data,
93 parameters.applet_resource_user_id); 98 image_data_buffer, parameters.applet_resource_user_id);
94 99
95 IPC::ResponseBuilder rb{ctx, 10}; 100 IPC::ResponseBuilder rb{ctx, 10};
96 rb.Push(result); 101 rb.Push(result);
97 rb.PushRaw(entry); 102 rb.PushRaw(entry);
98} 103}
99 104
105void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption report_option) {
106 auto& renderer = system.Renderer();
107 Layout::FramebufferLayout layout =
108 Layout::DefaultFrameLayout(screenshot_width, screenshot_height);
109
110 const Capture::ScreenShotAttribute attribute{
111 .unknown_0{},
112 .orientation = Capture::AlbumImageOrientation::None,
113 .unknown_1{},
114 .unknown_2{},
115 };
116
117 renderer.RequestScreenshot(
118 image_data.data(),
119 [attribute, report_option, this](bool invert_y) {
120 // Convert from BGRA to RGBA
121 for (std::size_t i = 0; i < image_data.size(); i += bytes_per_pixel) {
122 const u8 temp = image_data[i];
123 image_data[i] = image_data[i + 2];
124 image_data[i + 2] = temp;
125 }
126
127 Capture::ApplicationAlbumEntry entry{};
128 manager->FlipVerticallyOnWrite(invert_y);
129 manager->SaveScreenShot(entry, attribute, report_option, image_data, {});
130 },
131 layout);
132}
133
100} // namespace Service::Capture 134} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_su.h b/src/core/hle/service/caps/caps_su.h
index 89e71f506..21912e95f 100644
--- a/src/core/hle/service/caps/caps_su.h
+++ b/src/core/hle/service/caps/caps_su.h
@@ -10,6 +10,7 @@ class System;
10} 10}
11 11
12namespace Service::Capture { 12namespace Service::Capture {
13enum class AlbumReportOption : s32;
13class AlbumManager; 14class AlbumManager;
14 15
15class IScreenShotApplicationService final : public ServiceFramework<IScreenShotApplicationService> { 16class IScreenShotApplicationService final : public ServiceFramework<IScreenShotApplicationService> {
@@ -18,11 +19,19 @@ public:
18 std::shared_ptr<AlbumManager> album_manager); 19 std::shared_ptr<AlbumManager> album_manager);
19 ~IScreenShotApplicationService() override; 20 ~IScreenShotApplicationService() override;
20 21
22 void CaptureAndSaveScreenshot(AlbumReportOption report_option);
23
21private: 24private:
25 static constexpr std::size_t screenshot_width = 1280;
26 static constexpr std::size_t screenshot_height = 720;
27 static constexpr std::size_t bytes_per_pixel = 4;
28
22 void SetShimLibraryVersion(HLERequestContext& ctx); 29 void SetShimLibraryVersion(HLERequestContext& ctx);
23 void SaveScreenShotEx0(HLERequestContext& ctx); 30 void SaveScreenShotEx0(HLERequestContext& ctx);
24 void SaveScreenShotEx1(HLERequestContext& ctx); 31 void SaveScreenShotEx1(HLERequestContext& ctx);
25 32
33 std::array<u8, screenshot_width * screenshot_height * bytes_per_pixel> image_data;
34
26 std::shared_ptr<AlbumManager> manager; 35 std::shared_ptr<AlbumManager> manager;
27}; 36};
28 37