diff --git a/nx/include/switch.h b/nx/include/switch.h index fab2a134..ecbb0d71 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -135,6 +135,7 @@ extern "C" { #include "switch/applets/album_la.h" #include "switch/applets/friends_la.h" #include "switch/applets/hid_la.h" +#include "switch/applets/mii_la.h" #include "switch/applets/nfp_la.h" #include "switch/applets/pctlauth.h" #include "switch/applets/psel.h" diff --git a/nx/include/switch/applets/mii_la.h b/nx/include/switch/applets/mii_la.h new file mode 100644 index 00000000..d0f8c15e --- /dev/null +++ b/nx/include/switch/applets/mii_la.h @@ -0,0 +1,67 @@ +/** + * @file mii_la.h + * @brief Wrapper for using the MiiEdit LibraryApplet. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/mii.h" + +/// AppletMode +typedef enum { + NfpLaMiiLaAppletMode_ShowMiiEdit = 0, ///< ShowMiiEdit + NfpLaMiiLaAppletMode_AppendMii = 1, ///< AppendMii + NfpLaMiiLaAppletMode_AppendMiiImage = 2, ///< AppendMiiImage + NfpLaMiiLaAppletMode_UpdateMiiImage = 3, ///< UpdateMiiImage +} MiiLaAppletMode; + +/// AppletInput +typedef struct { + u32 unk_x0; ///< Always set to value 0x3. + 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. + Uuid used_uuid; ///< UsedUuid. Only used with \ref MiiLaAppletMode ::NfpLaMiiLaAppletMode_UpdateMiiImage. + u8 unk_x9C[0x64]; ///< Unused +} MiiLaAppletInput; + +/// AppletOutput +typedef struct { + u32 res; ///< Result: 0 = Success, 1 = Cancel. + s32 index; ///< s32 Index. Only set when Result is Success, where \ref MiiLaAppletMode isn't ::NfpLaMiiLaAppletMode_ShowMiiEdit. + u8 unk_x8[0x18]; ///< Unused +} MiiLaAppletOutput; + +/** + * @brief Launches the applet for ShowMiiEdit. + * @param[in] special_key_code \ref MiiSpecialKeyCode + */ +Result miiLaShowMiiEdit(MiiSpecialKeyCode special_key_code); + +/** + * @brief Launches the applet for AppendMii. + * @param[in] special_key_code \ref MiiSpecialKeyCode + * @param[out] index Output Index. + */ +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[out] index Output Index. + */ +Result miiLaAppendMiiImage(MiiSpecialKeyCode special_key_code, const Uuid *valid_uuid_array, s32 count, s32 *index); + +/** + * @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] 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); + diff --git a/nx/source/applets/mii_la.c b/nx/source/applets/mii_la.c new file mode 100644 index 00000000..1614301f --- /dev/null +++ b/nx/source/applets/mii_la.c @@ -0,0 +1,105 @@ +#include +#include "libapplet_internal.h" +#include "applets/mii_la.h" + +static Result _miiLaShow(const MiiLaAppletInput *in, MiiLaAppletOutput *out) { + Result rc=0; + AppletHolder holder; + AppletStorage storage; + + rc = appletCreateLibraryApplet(&holder, AppletId_miiEdit, LibAppletMode_AllForeground); + if (R_FAILED(rc)) return rc; + + if (R_SUCCEEDED(rc)) rc = libappletPushInData(&holder, in, sizeof(*in)); + + if (R_SUCCEEDED(rc)) rc = appletHolderStart(&holder); + + appletHolderJoin(&holder); + + LibAppletExitReason reason = appletHolderGetExitReason(&holder); + + if (reason == LibAppletExitReason_Canceled || reason == LibAppletExitReason_Abnormal || reason == LibAppletExitReason_Unexpected) { + rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit); + } + + if (R_SUCCEEDED(rc)) rc = appletHolderPopOutData(&holder, &storage); + + if (R_SUCCEEDED(rc)) { + rc = appletStorageRead(&storage, 0, out, sizeof(*out)); + appletStorageClose(&storage); + } + + appletHolderClose(&holder); + + return rc; +} + +static void _miiLaInitializeValidUuidArray(MiiLaAppletInput *in, const Uuid *in_array, s32 count) { + memset(in->valid_uuid_array, 0, sizeof(in->valid_uuid_array)); + + if (count > 8) count = 8; + for (s32 i=0; ivalid_uuid_array[i] = in_array[i]; +} + +static Result _miiLaGetResult(MiiLaAppletOutput *out) { + Result rc=0; + + if (out->res == 0) + rc = 0; + else if (out->res == 1) + rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit); + else + rc = MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); + + return rc; +} + +Result miiLaShowMiiEdit(MiiSpecialKeyCode special_key_code) { + Result rc=0; + MiiLaAppletInput in = {.unk_x0 = 0x3, .mode = NfpLaMiiLaAppletMode_ShowMiiEdit, .special_key_code = special_key_code}; + MiiLaAppletOutput out={0}; + + rc = _miiLaShow(&in, &out); + if (R_SUCCEEDED(rc)) { + rc = _miiLaGetResult(&out); + rc = R_VALUE(rc) == MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit) ? 0 : rc; + } + return rc; +} + +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}; + MiiLaAppletOutput out={0}; + + rc = _miiLaShow(&in, &out); + if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(&out); + 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}; + MiiLaAppletOutput out={0}; + + _miiLaInitializeValidUuidArray(&in, valid_uuid_array, count); + rc = _miiLaShow(&in, &out); + if (R_SUCCEEDED(rc)) rc = _miiLaGetResult(&out); + 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}; + 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); + if (R_SUCCEEDED(rc)) *index = out.index; + return rc; +} +