From 4b550000208b255d5356752fe2e4736e4af719c4 Mon Sep 17 00:00:00 2001 From: XorTroll Date: Fri, 4 Oct 2019 21:05:59 +0200 Subject: [PATCH] Add psel (playerSelect) support --- nx/include/switch.h | 1 + nx/include/switch/applets/psel.h | 69 ++++++++++++++++++++++++++++++++ nx/source/applets/psel.c | 31 ++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 nx/include/switch/applets/psel.h create mode 100644 nx/source/applets/psel.c diff --git a/nx/include/switch.h b/nx/include/switch.h index 15697d1d..72b039e4 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -112,6 +112,7 @@ extern "C" { #include "switch/applets/libapplet.h" #include "switch/applets/pctlauth.h" +#include "switch/applets/psel.h" #include "switch/applets/error.h" #include "switch/applets/swkbd.h" #include "switch/applets/web.h" diff --git a/nx/include/switch/applets/psel.h b/nx/include/switch/applets/psel.h new file mode 100644 index 00000000..f10e241a --- /dev/null +++ b/nx/include/switch/applets/psel.h @@ -0,0 +1,69 @@ +/** + * @file psel.h + * @brief Wrapper for using playerSelect applet (user selection applet). + * @author XorTroll + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/applet.h" +#include "../services/set.h" + +// playerSelect applet modes. There are more of them related to network accounts. +typedef enum { + PselMode_Normal = 0, ///< Simple user selection (new users cannot be created). + PselMode_UserCreation = 1, ///< Only user creation (the user is later returned). + PselMode_ForStarter = 2, ///< Mode "starter" uses to register the console's first user on the initial setup +} PselMode; + +// Config data for playerSelect applet. +typedef struct { + u32 mode; ///< Mode, see \ref PselMode. + u8 unk1[0x8f]; ///< Unknown + u8 userCreationFlag; ///< If set, a new user can be created and chosen (for ::PselMode_Normal). + u8 omitOptionFlag; ///< If set, an "Omit" button is shown. + u8 unk2[11]; ///< Unknown +} PselUserSelectionConfig; + +// Result data returned after execution. +typedef struct { + u32 result; ///< Result (0 = Success, 2 = Failure) + u128 userId; ///< UUID of selected user +} PselResult; + +// Config holder structure. +typedef struct { + PselUserSelectionConfig config; ///< User selection config +} PselConfig; + +/** + * @brief Creates a new config for playerSelect applet with the specified mode. + * @param c PselConfig struct. + * @param mode playerSelect applet mode. + */ +Result pselConfigCreate(PselConfig *c, PselMode mode); + +/** + * @brief Sets the UserCreation flag. + * @param c PselConfig struct. + * @param flag Flag value. + */ +static inline void pselConfigSetUserCreationFlag(PselConfig *c, bool flag) { + c->config.userCreationFlag = flag; +} + +/** + * @brief Sets the OmitOption flag. + * @param c PselConfig struct. + * @param flag Flag value. + */ +static inline void pselConfigSetOmitOptionFlag(PselConfig *c, bool flag) { + c->config.omitOptionFlag = flag; +} + +/** + * @brief Shows the applet with the specified config. + * @param c PselConfig struct. + * @param out_uid Output user ID. + */ +Result pselConfigShow(PselConfig *c, u128 *out_uid); \ No newline at end of file diff --git a/nx/source/applets/psel.c b/nx/source/applets/psel.c new file mode 100644 index 00000000..997136b4 --- /dev/null +++ b/nx/source/applets/psel.c @@ -0,0 +1,31 @@ +#include +#include "types.h" +#include "result.h" +#include "services/applet.h" +#include "services/set.h" +#include "applets/libapplet.h" +#include "applets/psel.h" +#include "runtime/hosversion.h" + +Result pselConfigCreate(PselConfig *c, PselMode mode) { + memset(c, 0, sizeof(PselConfig)); + c->config.mode = mode; + return 0; +} + +Result pselConfigShow(PselConfig *c, u128 *out_uid) { + Result rc = 0; + LibAppletArgs args; + libappletArgsCreate(&args, 0); + PselResult res; + size_t reply_size; + + rc = libappletLaunch(AppletId_playerSelect, &args, &c->config, sizeof(c->config), &res, sizeof(res), &reply_size); + + if (R_SUCCEEDED(rc)) { + if (R_FAILED(res.result)) rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit); + if (R_SUCCEEDED(rc)) *out_uid = res.userId; + } + + return rc; +}