From d4014bde62db51679d6ef634b87c606ce1aad698 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Thu, 17 Dec 2020 00:21:47 -0500 Subject: [PATCH] miiLa: Added for support for 10.2.0 functionality + various fixes. --- nx/include/switch/applets/mii_la.h | 50 ++++++++++++++++---- nx/source/applets/mii_la.c | 75 +++++++++++++++++++++++------- 2 files changed, 100 insertions(+), 25 deletions(-) diff --git a/nx/include/switch/applets/mii_la.h b/nx/include/switch/applets/mii_la.h index b0c8a250..14f7b3a8 100644 --- a/nx/include/switch/applets/mii_la.h +++ b/nx/include/switch/applets/mii_la.h @@ -10,18 +10,26 @@ /// AppletMode typedef enum { - NfpLaMiiLaAppletMode_ShowMiiEdit = 0, ///< ShowMiiEdit - NfpLaMiiLaAppletMode_AppendMii = 1, ///< AppendMii - NfpLaMiiLaAppletMode_AppendMiiImage = 2, ///< AppendMiiImage - NfpLaMiiLaAppletMode_UpdateMiiImage = 3, ///< UpdateMiiImage + MiiLaAppletMode_ShowMiiEdit = 0, ///< ShowMiiEdit + MiiLaAppletMode_AppendMii = 1, ///< AppendMii + MiiLaAppletMode_AppendMiiImage = 2, ///< AppendMiiImage + MiiLaAppletMode_UpdateMiiImage = 3, ///< UpdateMiiImage + MiiLaAppletMode_CreateMii = 4, ///< [10.2.0+] CreateMii + MiiLaAppletMode_EditMii = 5, ///< [10.2.0+] EditMii } MiiLaAppletMode; /// AppletInput typedef struct { - u32 unk_x0; ///< Always set to value 0x3. + s32 version; ///< Version u32 mode; ///< \ref MiiLaAppletMode s32 special_key_code; ///< \ref MiiSpecialKeyCode - Uuid valid_uuid_array[8]; ///< ValidUuidArray. Only used with \ref MiiLaAppletMode ::NfpLaMiiLaAppletMode_AppendMiiImage / ::NfpLaMiiLaAppletMode_UpdateMiiImage. + union { + Uuid valid_uuid_array[8]; ///< ValidUuidArray. Only used with \ref MiiLaAppletMode ::NfpLaMiiLaAppletMode_AppendMiiImage / ::NfpLaMiiLaAppletMode_UpdateMiiImage. + struct { + MiiCharInfo char_info; ///< \ref MiiCharInfo + u8 unused_x64[0x28]; ///< Unused + } char_info; + }; Uuid used_uuid; ///< UsedUuid. Only used with \ref MiiLaAppletMode ::NfpLaMiiLaAppletMode_UpdateMiiImage. u8 unk_x9C[0x64]; ///< Unused } MiiLaAppletInput; @@ -33,6 +41,13 @@ typedef struct { u8 unk_x8[0x18]; ///< Unused } MiiLaAppletOutput; +/// AppletOutputForCharInfoEditing +typedef struct { + u32 res; ///< MiiLaAppletOutput::res + MiiCharInfo char_info; ///< \ref MiiCharInfo + u8 unused[0x24]; ///< Unused +} MiiLaAppletOutputForCharInfoEditing; + /** * @brief Launches the applet for ShowMiiEdit. * @param[in] special_key_code \ref MiiSpecialKeyCode @@ -50,7 +65,7 @@ Result miiLaAppendMii(MiiSpecialKeyCode special_key_code, s32 *index); * @brief Launches the applet for AppendMiiImage. * @param[in] special_key_code \ref MiiSpecialKeyCode * @param[in] valid_uuid_array Input array of Uuid. - * @oaram[in] count Total entries for the valid_uuid_array. Must be 0-8. + * @param[in] count Total entries for the valid_uuid_array. Must be 0-8. * @param[out] index Output Index. */ Result miiLaAppendMiiImage(MiiSpecialKeyCode special_key_code, const Uuid *valid_uuid_array, s32 count, s32 *index); @@ -59,9 +74,28 @@ Result miiLaAppendMiiImage(MiiSpecialKeyCode special_key_code, const Uuid *valid * @brief Launches the applet for UpdateMiiImage. * @param[in] special_key_code \ref MiiSpecialKeyCode * @param[in] valid_uuid_array Input array of Uuid. - * @oaram[in] count Total entries for the valid_uuid_array. Must be 0-8. + * @param[in] count Total entries for the valid_uuid_array. Must be 0-8. * @param[in] used_uuid UsedUuid * @param[out] index Output Index. */ Result miiLaUpdateMiiImage(MiiSpecialKeyCode special_key_code, const Uuid *valid_uuid_array, s32 count, Uuid used_uuid, s32 *index); +/** + * @brief Launches the applet for CreateMii. + * @note This creates a Mii and returns it, without saving it in the database. + * @note Only available on [10.2.0+]. + * @param[in] special_key_code \ref MiiSpecialKeyCode + * @param[out] out_char \ref MiiCharInfo + */ +Result miiLaCreateMii(MiiSpecialKeyCode special_key_code, MiiCharInfo *out_char); + +/** + * @brief Launches the applet for EditMii. + * @note This edits the specified Mii and returns it, without saving it in the database. + * @note Only available on [10.2.0+]. + * @param[in] special_key_code \ref MiiSpecialKeyCode + * @param[in] in_char \ref MiiCharInfo + * @param[out] out_char \ref MiiCharInfo + */ +Result miiLaEditMii(MiiSpecialKeyCode special_key_code, const MiiCharInfo *in_char, MiiCharInfo *out_char); + diff --git a/nx/source/applets/mii_la.c b/nx/source/applets/mii_la.c index f15e94c8..3070a9b3 100644 --- a/nx/source/applets/mii_la.c +++ b/nx/source/applets/mii_la.c @@ -1,8 +1,17 @@ #include #include "libapplet_internal.h" #include "applets/mii_la.h" +#include "runtime/hosversion.h" -static Result _miiLaShow(const MiiLaAppletInput *in, MiiLaAppletOutput *out) { +static s32 _miiLaGetVersion(void) { + s32 version = 0x3; + + if (hosversionAtLeast(10,2,0)) version = 0x4; + + return version; +} + +static Result _miiLaShow(const MiiLaAppletInput *in, void* out, size_t out_size) { Result rc=0; AppletHolder holder; AppletStorage storage; @@ -25,7 +34,7 @@ static Result _miiLaShow(const MiiLaAppletInput *in, MiiLaAppletOutput *out) { if (R_SUCCEEDED(rc)) rc = appletHolderPopOutData(&holder, &storage); if (R_SUCCEEDED(rc)) { - rc = appletStorageRead(&storage, 0, out, sizeof(*out)); + rc = appletStorageRead(&storage, 0, out, out_size); appletStorageClose(&storage); } @@ -41,12 +50,12 @@ static void _miiLaInitializeValidUuidArray(MiiLaAppletInput *in, const Uuid *in_ for (s32 i=0; ivalid_uuid_array[i] = in_array[i]; } -static Result _miiLaGetResult(MiiLaAppletOutput *out) { +static Result _miiLaGetResult(u32 res) { Result rc=0; - if (out->res == 0) + if (res == 0) rc = 0; - else if (out->res == 1) + else if (res == 1) rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit); else rc = MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); @@ -56,12 +65,12 @@ static Result _miiLaGetResult(MiiLaAppletOutput *out) { Result miiLaShowMiiEdit(MiiSpecialKeyCode special_key_code) { Result rc=0; - MiiLaAppletInput in = {.unk_x0 = 0x3, .mode = NfpLaMiiLaAppletMode_ShowMiiEdit, .special_key_code = special_key_code}; + MiiLaAppletInput in = {.version = _miiLaGetVersion(), .mode = MiiLaAppletMode_ShowMiiEdit, .special_key_code = special_key_code}; MiiLaAppletOutput out={0}; - rc = _miiLaShow(&in, &out); + rc = _miiLaShow(&in, &out, sizeof(out)); if (R_SUCCEEDED(rc)) { - rc = _miiLaGetResult(&out); + rc = _miiLaGetResult(out.res); rc = R_VALUE(rc) == MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit) ? 0 : rc; } return rc; @@ -69,37 +78,69 @@ Result miiLaShowMiiEdit(MiiSpecialKeyCode special_key_code) { Result miiLaAppendMii(MiiSpecialKeyCode special_key_code, s32 *index) { Result rc=0; - MiiLaAppletInput in = {.unk_x0 = 0x3, .mode = NfpLaMiiLaAppletMode_AppendMii, .special_key_code = special_key_code}; + MiiLaAppletInput in = {.version = _miiLaGetVersion(), .mode = MiiLaAppletMode_AppendMii, .special_key_code = special_key_code}; MiiLaAppletOutput out={0}; - rc = _miiLaShow(&in, &out); - if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(&out); + rc = _miiLaShow(&in, &out, sizeof(out)); + if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(out.res); if (R_SUCCEEDED(rc)) *index = out.index; return rc; } Result miiLaAppendMiiImage(MiiSpecialKeyCode special_key_code, const Uuid *valid_uuid_array, s32 count, s32 *index) { Result rc=0; - MiiLaAppletInput in = {.unk_x0 = 0x3, .mode = NfpLaMiiLaAppletMode_AppendMiiImage, .special_key_code = special_key_code}; + MiiLaAppletInput in = {.version = _miiLaGetVersion(), .mode = MiiLaAppletMode_AppendMiiImage, .special_key_code = special_key_code}; MiiLaAppletOutput out={0}; _miiLaInitializeValidUuidArray(&in, valid_uuid_array, count); - rc = _miiLaShow(&in, &out); - if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(&out); + rc = _miiLaShow(&in, &out, sizeof(out)); + if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(out.res); if (R_SUCCEEDED(rc)) *index = out.index; return rc; } Result miiLaUpdateMiiImage(MiiSpecialKeyCode special_key_code, const Uuid *valid_uuid_array, s32 count, Uuid used_uuid, s32 *index) { Result rc=0; - MiiLaAppletInput in = {.unk_x0 = 0x3, .mode = NfpLaMiiLaAppletMode_UpdateMiiImage, .special_key_code = special_key_code}; + MiiLaAppletInput in = {.version = _miiLaGetVersion(), .mode = MiiLaAppletMode_UpdateMiiImage, .special_key_code = special_key_code}; MiiLaAppletOutput out={0}; _miiLaInitializeValidUuidArray(&in, valid_uuid_array, count); in.used_uuid = used_uuid; - rc = _miiLaShow(&in, &out); - if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(&out); + rc = _miiLaShow(&in, &out, sizeof(out)); + if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(out.res); if (R_SUCCEEDED(rc)) *index = out.index; return rc; } +Result miiLaCreateMii(MiiSpecialKeyCode special_key_code, MiiCharInfo *out_char) { + Result rc=0; + MiiLaAppletInput in = {.version = _miiLaGetVersion(), .mode = MiiLaAppletMode_CreateMii, .special_key_code = special_key_code}; + MiiLaAppletOutputForCharInfoEditing out={0}; + + if (hosversionBefore(10,2,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + rc = _miiLaShow(&in, &out, sizeof(out)); + if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(out.res); + if (R_SUCCEEDED(rc)) *out_char = out.char_info; + return rc; +} + +Result miiLaEditMii(MiiSpecialKeyCode special_key_code, const MiiCharInfo *in_char, MiiCharInfo *out_char) { + Result rc=0; + MiiLaAppletInput in = {.version = _miiLaGetVersion(), .mode = MiiLaAppletMode_EditMii, .special_key_code = special_key_code}; + MiiLaAppletOutputForCharInfoEditing out={0}; + + if (hosversionBefore(10,2,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + // sdknso does various validation with in_char, we won't do so. + + in.char_info.char_info = *in_char; + + rc = _miiLaShow(&in, &out, sizeof(out)); + if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(out.res); + if (R_SUCCEEDED(rc)) *out_char = out.char_info; + return rc; +} +