diff --git a/nx/include/switch/services/caps.h b/nx/include/switch/services/caps.h index 740883a9..c145fba0 100644 --- a/nx/include/switch/services/caps.h +++ b/nx/include/switch/services/caps.h @@ -180,7 +180,7 @@ typedef struct { s64 width; ///< Width. Official sw copies this to a s32 output field. s64 height; ///< Height. Official sw copies this to a s32 output field. CapsScreenShotAttributeForApplication attr; ///< \ref CapsScreenShotAttributeForApplication - u8 unk_x50[0x400]; + u8 unk_x50[0x400]; ///< Unused. } CapsLoadAlbumScreenShotImageOutput; /// Gets the ShimLibraryVersion. diff --git a/nx/include/switch/services/capsa.h b/nx/include/switch/services/capsa.h index efb33b3f..0e2803b3 100644 --- a/nx/include/switch/services/capsa.h +++ b/nx/include/switch/services/capsa.h @@ -144,6 +144,21 @@ Result capsaLoadAlbumScreenShotImageEx(u64 *width, u64 *height, const CapsAlbumF */ Result capsaLoadAlbumScreenShotThumbnailImageEx(u64 *width, u64 *height, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size); +/** + * @brief Load the ScreenShotImage for the specified AlbumFile. + * @note Only available on [3.0.0+]. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[out] attr \ref CapsScreenShotAttributeForApplication + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] opts \ref CapsScreenShotDecodeOption + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsaLoadAlbumScreenShotImageEx0(u64 *width, u64 *height, CapsScreenShotAttributeForApplication *attr, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + /** * @brief Returns the AlbumUsage for a specified \ref CapsAlbumStorage. * @note Only available on [4.0.0+]. @@ -183,10 +198,38 @@ Result capsaGetRequiredStorageSpaceSizeToCopyAll(CapsAlbumStorage dst_storage, C /** * @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. + * @note Only available on [3.0.0+]. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[out] attr \ref CapsScreenShotAttributeForApplication + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] opts \ref CapsScreenShotDecodeOption + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsLoadAlbumScreenShotThumbnailImageEx0(u64 *width, u64 *height, CapsScreenShotAttributeForApplication *attr, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Load the ScreenShotImage for the specified AlbumFile. * @note Only available on [4.0.0+]. * @param[in] file_id \ref CapsAlbumFileId * @param[in] opts \ref CapsScreenShotDecodeOption - * @param[out] out \ref CapsLoadAlbumScreenShotImageOutputForApplication + * @param[out] out \ref CapsLoadAlbumScreenShotImageOutput + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsaLoadAlbumScreenShotImageEx1(const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, CapsLoadAlbumScreenShotImageOutput *out, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. + * @note Only available on [4.0.0+]. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] opts \ref CapsScreenShotDecodeOption + * @param[out] out \ref CapsLoadAlbumScreenShotImageOutput * @param[out] image RGBA8 image output buffer. * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. diff --git a/nx/source/services/capsa.c b/nx/source/services/capsa.c index e1c7b526..89b6ab66 100644 --- a/nx/source/services/capsa.c +++ b/nx/source/services/capsa.c @@ -57,7 +57,7 @@ Result capsaDeleteAlbumFile(const CapsAlbumFileId *file_id) { } Result capsaStorageCopyAlbumFile(const CapsAlbumFileId *file_id, CapsAlbumStorage dst_storage) { - struct { + const struct { u8 storage; u8 pad_x1[0x7]; CapsAlbumFileId file_id; @@ -113,7 +113,7 @@ Result capsaLoadAlbumScreenShotThumbnailImage(u64 *width, u64 *height, const Cap static Result _capsaLoadAlbumScreenshotEx(u64 *width, u64 *height, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size, u32 cmd_id) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - struct { + const struct { CapsAlbumFileId file_id; CapsScreenShotDecodeOption opts; } in = { *file_id, *opts }; @@ -138,6 +138,32 @@ Result capsaLoadAlbumScreenShotThumbnailImageEx(u64 *width, u64 *height, const C return _capsaLoadAlbumScreenshotEx(width, height, file_id, opts, image, image_size, workbuf, workbuf_size, 13); } +Result _capsaLoadAlbumScreenShotEx0(u64 *width, u64 *height, CapsScreenShotAttributeForApplication *attr, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size, u32 cmd_id) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + const struct { + CapsAlbumFileId file_id; + CapsScreenShotDecodeOption opts; + } in = { *file_id, *opts }; + struct { + CapsScreenShotAttributeForApplication attr; + s64 width; + s64 height; + } out = {0}; + Result rc = serviceDispatchInOut(&g_capsaSrv, cmd_id, in, out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { image, image_size }, { workbuf, workbuf_size } }, + ); + *attr = out.attr; + *width = out.width; + *height = out.height; + return rc; +} + +Result capsaLoadAlbumScreenShotImageEx0(u64 *width, u64 *height, CapsScreenShotAttributeForApplication *attr, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size) { + return _capsaLoadAlbumScreenShotEx0(width, height, attr, file_id, opts, image, image_size, workbuf, workbuf_size, 14); +} + Result capsaGetAlbumUsage3(CapsAlbumStorage storage, CapsAlbumUsage3 *out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); @@ -166,26 +192,38 @@ Result capsaGetAutoSavingStorage(CapsAlbumStorage *storage) { } Result capsaGetRequiredStorageSpaceSizeToCopyAll(CapsAlbumStorage dst_storage, CapsAlbumStorage src_storage, u64 *out) { - struct { + const struct { u8 dest; u8 src; } in = { dst_storage, src_storage }; return serviceDispatchInOut(&g_capsaSrv, 501, in, *out); } -Result capsaLoadAlbumScreenShotThumbnailImageEx1(const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, CapsLoadAlbumScreenShotImageOutput *out, void* image, u64 image_size, void* workbuf, u64 workbuf_size) { +Result capsLoadAlbumScreenShotThumbnailImageEx0(u64 *width, u64 *height, CapsScreenShotAttributeForApplication *attr, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size) { + return _capsaLoadAlbumScreenShotEx0(width, height, attr, file_id, opts, image, image_size, workbuf, workbuf_size, 1001); +} + +Result _capsaLoadAlbumScreenShotEx1(const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, CapsLoadAlbumScreenShotImageOutput *out, void* image, u64 image_size, void* workbuf, u64 workbuf_size, u32 cmd_id) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - struct { + const struct { CapsAlbumFileId file_id; CapsScreenShotDecodeOption opts; } in = { *file_id, *opts }; - return serviceDispatchIn(&g_capsaSrv, 1003, in, + return serviceDispatchIn(&g_capsaSrv, cmd_id, in, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_FixedSize, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { out, sizeof(CapsLoadAlbumScreenShotImageOutput) }, { image, image_size }, { workbuf, workbuf_size } }, ); } +Result capsaLoadAlbumScreenShotImageEx1(const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, CapsLoadAlbumScreenShotImageOutput *out, void* image, u64 image_size, void* workbuf, u64 workbuf_size) { + return _capsaLoadAlbumScreenShotEx1(file_id, opts, out, image, image_size, workbuf, workbuf_size, 1002); +} + +Result capsaLoadAlbumScreenShotThumbnailImageEx1(const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, CapsLoadAlbumScreenShotImageOutput *out, void* image, u64 image_size, void* workbuf, u64 workbuf_size) { + return _capsaLoadAlbumScreenShotEx1(file_id, opts, out, image, image_size, workbuf, workbuf_size, 1003); +} + Result capsaForceAlbumUnmounted(CapsAlbumStorage storage) { return _capsaCmdInU8NoOut(&g_capsaSrv, storage, 8001); }