diff --git a/nx/include/switch.h b/nx/include/switch.h index 465d4262..b51d25d5 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -94,6 +94,7 @@ extern "C" { #include "switch/services/caps.h" #include "switch/services/capsa.h" #include "switch/services/capsc.h" +#include "switch/services/capsdc.h" #include "switch/services/capsu.h" #include "switch/services/capssc.h" #include "switch/services/capssu.h" diff --git a/nx/include/switch/services/caps.h b/nx/include/switch/services/caps.h index 29dc936a..a52ca0f5 100644 --- a/nx/include/switch/services/caps.h +++ b/nx/include/switch/services/caps.h @@ -65,7 +65,10 @@ typedef struct { /// ScreenShotDecodeOption typedef struct { - u8 unk_x0[0x20]; ///< Unknown. Set to all-zero by official sw. + u8 fancy_upsampling; ///< See libjpeg-turbo do_fancy_upsampling. + u8 block_smoothing; ///< See libjpeg-turbo do_block_smoothing. + u8 pad_x2[0x6]; ///< Padding. + u64 unk_x8[0x3]; ///< Unknown. Ignored by official sw. } CapsScreenShotDecodeOption; /// AlbumFileDateTime. This corresponds to each field in the Album entry filename, prior to the "-": "YYYYMMDDHHMMSSII". diff --git a/nx/include/switch/services/capsdc.h b/nx/include/switch/services/capsdc.h new file mode 100644 index 00000000..3498e9cb --- /dev/null +++ b/nx/include/switch/services/capsdc.h @@ -0,0 +1,32 @@ +/** + * @file capsdc.h + * @brief Jpeg Decoder (caps:dc) service IPC wrapper. Only available on [4.0.0+]. + * @note Only holds one session that is occupied by capsrv. + * @author Behemoth + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/caps.h" + +/// Initialize caps:dc +Result capsdcInitialize(void); + +/// Exit caps:dc. +void capsdcExit(void); + +/// Gets the Service for caps:dc. +Service* capsdcGetServiceSession(void); + +/** + * @brief Decodes a jpeg buffer into RGBX. + * @param[in] width Image width. + * @param[in] height Image height. + * @param[in] opts \ref CapsScreenShotDecodeOption. + * @param[in] jpeg Jpeg image input buffer. + * @param[in] jpeg_size Input image buffer size. + * @param[out] out_image RGBA8 image output buffer. + * @param[in] out_image_size Output image buffer size, should be at least large enough for RGBA8 width x height. + */ +Result capsdcDecodeJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_image, size_t out_image_size); diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index 527646e6..0da76c50 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -170,6 +170,12 @@ typedef enum { FsCustomStorageId_SdCard = 1, } FsCustomStorageId; +/// ImageDirectoryId +typedef enum { + FsImageDirectoryId_Nand = 0, + FsImageDirectoryId_Sd = 1, +} FsImageDirectoryId; + /// SaveDataSpaceId typedef enum { FsSaveDataSpaceId_System = 0, ///< System @@ -329,6 +335,7 @@ Result fsWriteSaveDataFileSystemExtraData(const void* buf, size_t len, FsSaveDat Result fsOpenSaveDataInfoReader(FsSaveDataInfoReader* out, FsSaveDataSpaceId save_data_space_id); +Result fsOpenImageDirectoryFileSystem(FsFileSystem* out, FsImageDirectoryId image_directory_id); Result fsOpenContentStorageFileSystem(FsFileSystem* out, FsContentStorageId content_storage_id); Result fsOpenCustomStorageFileSystem(FsFileSystem* out, FsCustomStorageId custom_storage_id); /// [7.0.0+] diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index e347379e..f926d6cd 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -422,7 +422,7 @@ typedef struct SixAxisSensorValues { HidVector orientation[3]; } SixAxisSensorValues; -#define JOYSTICK_MAX (0x8000) +#define JOYSTICK_MAX (0x7FFF) #define JOYSTICK_MIN (-0x8000) // End enums and output structs diff --git a/nx/include/switch/services/set.h b/nx/include/switch/services/set.h index 7fe5015d..fda2445b 100644 --- a/nx/include/switch/services/set.h +++ b/nx/include/switch/services/set.h @@ -959,7 +959,7 @@ Result setsysSetChineseTraditionalInputMethod(SetChineseTraditionalInputMethod m /** * @brief Gets the \ref SetSysHomeMenuScheme. - * @note Only available on [9.0.0+]. + * @note Only available on [8.1.1+]. * @param[out] out \ref SetSysHomeMenuScheme */ Result setsysGetHomeMenuScheme(SetSysHomeMenuScheme *out); diff --git a/nx/source/services/capsdc.c b/nx/source/services/capsdc.c new file mode 100644 index 00000000..7297e58a --- /dev/null +++ b/nx/source/services/capsdc.c @@ -0,0 +1,41 @@ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "service_guard.h" +#include "runtime/hosversion.h" +#include "services/capsdc.h" + +static Service g_capsdcSrv; + +NX_GENERATE_SERVICE_GUARD(capsdc); + +Result _capsdcInitialize(void) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return smGetService(&g_capsdcSrv, "caps:dc"); +} + +void _capsdcCleanup(void) { + serviceClose(&g_capsdcSrv); +} + +Service* capsdcGetServiceSession(void) { + return &g_capsdcSrv; +} + +Result capsdcDecodeJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_image, size_t out_image_size) { + const struct { + u32 width; + u32 height; + CapsScreenShotDecodeOption opts; + } in = { width, height, *opts }; + return serviceDispatchIn(&g_capsdcSrv, 3001, in, + .buffer_attrs = { + SfBufferAttr_In | SfBufferAttr_HipcMapAlias, + SfBufferAttr_Out | SfBufferAttr_HipcMapAlias | SfBufferAttr_HipcMapTransferAllowsNonSecure, + }, + .buffers = { + { jpeg, jpeg_size }, + { out_image, out_image_size }, + } + ); +} diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index 8ab67afa..ba5bda71 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -351,6 +351,14 @@ Result fsOpenSaveDataInfoReader(FsSaveDataInfoReader* out, FsSaveDataSpaceId sav } } +Result fsOpenImageDirectoryFileSystem(FsFileSystem* out, FsImageDirectoryId image_directory_id) { + u32 tmp=image_directory_id; + return _fsObjectDispatchIn(&g_fsSrv, 100, tmp, + .out_num_objects = 1, + .out_objects = &out->s, + ); +} + Result fsOpenContentStorageFileSystem(FsFileSystem* out, FsContentStorageId content_storage_id) { u32 tmp=content_storage_id; return _fsObjectDispatchIn(&g_fsSrv, 110, tmp, diff --git a/nx/source/services/set.c b/nx/source/services/set.c index 3655e81f..131a5e07 100644 --- a/nx/source/services/set.c +++ b/nx/source/services/set.c @@ -727,7 +727,7 @@ Result setsysSetChineseTraditionalInputMethod(SetChineseTraditionalInputMethod m } Result setsysGetHomeMenuScheme(SetSysHomeMenuScheme *out) { - if (hosversionBefore(9,0,0)) + if (hosversionBefore(8,1,1)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return serviceDispatchOut(&g_setsysSrv, 174, *out);