From 0cff65edddfd0c700555b598977deeb708115ba1 Mon Sep 17 00:00:00 2001 From: Narr the Reg <5944268+german77@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:25:42 -0600 Subject: [PATCH 1/3] swkbd: Add support for multiple FW versions --- CMakeLists.txt | 3 +- include/nn/applet.h | 3 +- include/nn/swkbd/swkbd.h | 98 +++++++++++++++++++++++++++++++++++----- 3 files changed, 90 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77d547e..2c22d4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,6 +188,7 @@ add_library(NintendoSDK OBJECT include/nn/ui2d/Parts.h include/nn/ui2d/Types.h include/nn/ui2d/Util.h + include/nn/swkbd/swkbd.h include/nn/g3d/BindFuncTable.h include/nn/g3d/ModelObj.h include/nn/g3d/ResMaterialAnim.h @@ -311,7 +312,7 @@ function(nn_ver ID) list(POP_FRONT VER MAJOR MINOR PATCH) foreach(VAR IN ITEMS MAJOR MINOR PATCH) - target_compile_definitions(NintendoSDK PRIVATE ${ID}_${VAR}=${${VAR}}) + target_compile_definitions(NintendoSDK PUBLIC ${ID}_${VAR}=${${VAR}}) endforeach() endfunction() diff --git a/include/nn/applet.h b/include/nn/applet.h index 12d892d..53681cd 100644 --- a/include/nn/applet.h +++ b/include/nn/applet.h @@ -2,4 +2,5 @@ namespace nn::applet { enum class ExitReason { Normal = 0, Canceled = 1, Abnormal = 2, Unexpected = 10 }; -} +typedef int LibraryAppletHandle; +} // namespace nn::applet diff --git a/include/nn/swkbd/swkbd.h b/include/nn/swkbd/swkbd.h index ffb322b..dd4148b 100644 --- a/include/nn/swkbd/swkbd.h +++ b/include/nn/swkbd/swkbd.h @@ -92,6 +92,8 @@ enum class DictionaryLang { enum class CloseResult { Enter, Cancel }; +enum class Trigger : u8 { Default }; + struct DictionaryInfo { u32 offset; u16 size; @@ -116,13 +118,27 @@ struct KeyboardConfig { bool isUseNewLine; bool isUseUtf8; bool isUseBlurBackground; - int _initialStringOffset; - int _initialStringLength; - int _userDictionaryOffset; - int _userDictionaryNum; - bool _isUseTextCheck; - void* _textCheckCallback; + int initialStringOffset; + int initialStringLength; + int userDictionaryOffset; + int userDictionaryNum; + bool isUseTextCheck; + void* textCheckCallback; + +#if NN_SDK_VER >= NN_MAKE_VER(3, 0, 0) int separateTextPos[0x8]; +#endif + +#if NN_SDK_VER >= NN_MAKE_VER(6, 0, 0) + u64 customDictionaryEntries[0x18]; + u8 customDictionaryNum; +#endif + +#if NN_SDK_VER >= NN_MAKE_VER(8, 0, 0) + u8 _3c1; + u8 filler[0xd]; + u8 trigger; +#endif }; struct ShowKeyboardArg { @@ -157,14 +173,63 @@ class String { int bufsize; }; -struct UserWord; // TODO contents missing +struct UserWord; // TODO contents missing +struct KbdConfig; // TODO contents missing + +struct CustomizedDictionarySet { + void* buffer; // 0x1000-byte aligned buffer. + int bufferSize; // 0x1000-byte aligned buffer size. + u64 entries[0x18]; + u16 totalEntries; +}; + +typedef TextCheckResult (*TextCheckCb)(void*, ulong*, String*); + +int ConvertUtf8ToUtf16(void*, int, const char*, int); +int ConvertUtf8ToUtf16(void*, int, const char*); +int GetLengthOfConvertedStringUtf8ToUtf16(const char*); +void MakePresetDefault(KeyboardConfig*); +void MakePresetPassword(KeyboardConfig*); +void MakePresetUsername(KeyboardConfig*); +void MakePresetDownloadCode(KeyboardConfig*); +Result GetInteractiveOutStorageCallback(nn::applet::LibraryAppletHandle, String*, + const ShowKeyboardArg&); +ulong GetRequiredTextCheckWorkBufferSize(); +void ReadCloseResultAndString(nn::applet::LibraryAppletHandle, CloseResult*, String*); +void CopyInitialStringInfo(ShowKeyboardArg*, int); +void CopyUserDictionaryInfo(ShowKeyboardArg*, int); + +#if NN_SDK_VER >= NN_MAKE_VER(3, 0, 0) +ulong GetRequiredWorkBufferSize(int); +#endif + +#if NN_SDK_VER >= NN_MAKE_VER(6, 0, 0) +void keyboardConfig2kbdConfig(const KeyboardConfig&, KbdConfig*); +#endif + +Result ShowKeyboard(String*, const ShowKeyboardArg&); + +#if NN_SDK_VER >= NN_MAKE_VER(8, 0, 0) +Result ShowKeyboard(String*, const ShowKeyboardArg&, Trigger); +#endif + +void InitializeKeyboardConfig(KeyboardConfig*); +void MakePreset(KeyboardConfig*, Preset); ulong GetRequiredWorkBufferSize(bool); + +#if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) && NN_SDK_VER < NN_MAKE_VER(2, 0, 0) +ulong GetRequiredWorkBufferSize(int); +#endif + +#if NN_SDK_VER >= NN_MAKE_VER(3, 0, 0) +ulong GetRequiredWorkBufferSize(); +#endif + +#if NN_SDK_VER < NN_MAKE_VER(2, 0, 0) ulong GetRequiredStringBufferSize(); -nn::applet::ExitReason GetExitReason(); -void MakePreset(KeyboardConfig*, Preset); -void SetHeaderText(KeyboardConfig*, const char16_t*); -void SetSubText(KeyboardConfig*, const char16_t*); +#endif + void SetOkText(KeyboardConfig*, const char16_t*); void SetOkTextUtf8(KeyboardConfig*, const char*); void SetLeftOptionalSymbolKey(KeyboardConfig*, char16_t); @@ -180,7 +245,16 @@ void SetGuideTextUtf8(KeyboardConfig*, const char*); void SetInitialText(ShowKeyboardArg*, const char16_t*); void SetInitialTextUtf8(ShowKeyboardArg*, const char*); void SetUserWordList(ShowKeyboardArg*, const UserWord*, int); -int ShowKeyboard(String*, const ShowKeyboardArg&); + +#if NN_SDK_VER >= NN_MAKE_VER(6, 0, 0) +void SetCustomizedDictionaries(ShowKeyboardArg*, const CustomizedDictionarySet&); +#endif + +void SetTextCheckCallback(ShowKeyboardArg*, TextCheckCb); + +#if NN_SDK_VER < NN_MAKE_VER(4, 0, 0) +nn::applet::ExitReason GetExitReason(); +#endif extern nn::applet::ExitReason g_ExitReason; } // namespace nn::swkbd From ed89a42f31a1ed7045f67c86251d3699e89e7255 Mon Sep 17 00:00:00 2001 From: Narr the Reg <5944268+german77@users.noreply.github.com> Date: Fri, 10 Apr 2026 11:10:47 -0600 Subject: [PATCH 2/3] First review --- include/nn/applet.h | 6 +++- include/nn/swkbd/swkbd.h | 65 ++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/include/nn/applet.h b/include/nn/applet.h index 53681cd..db48224 100644 --- a/include/nn/applet.h +++ b/include/nn/applet.h @@ -1,6 +1,10 @@ #pragma once +#include + namespace nn::applet { enum class ExitReason { Normal = 0, Canceled = 1, Abnormal = 2, Unexpected = 10 }; -typedef int LibraryAppletHandle; + +// TODO: Fill members of LibraryAppletHandle. This contains a service ctx +struct LibraryAppletHandle; } // namespace nn::applet diff --git a/include/nn/swkbd/swkbd.h b/include/nn/swkbd/swkbd.h index dd4148b..6f3bcc6 100644 --- a/include/nn/swkbd/swkbd.h +++ b/include/nn/swkbd/swkbd.h @@ -111,22 +111,22 @@ struct KeyboardConfig { char headerText[0x82]; char subText[0x102]; char guideText[0x202]; - int textMaxLength; - int textMinLength; + s32 textMaxLength; + s32 textMinLength; PasswordMode passwordMode; InputFormMode inputFormMode; bool isUseNewLine; bool isUseUtf8; bool isUseBlurBackground; - int initialStringOffset; - int initialStringLength; - int userDictionaryOffset; - int userDictionaryNum; + s32 initialStringOffset; + s32 initialStringLength; + s32 userDictionaryOffset; + s32 userDictionaryNum; bool isUseTextCheck; void* textCheckCallback; #if NN_SDK_VER >= NN_MAKE_VER(3, 0, 0) - int separateTextPos[0x8]; + s32 separateTextPos[0x8]; #endif #if NN_SDK_VER >= NN_MAKE_VER(6, 0, 0) @@ -137,7 +137,7 @@ struct KeyboardConfig { #if NN_SDK_VER >= NN_MAKE_VER(8, 0, 0) u8 _3c1; u8 filler[0xd]; - u8 trigger; + Trigger trigger; #endif }; @@ -153,11 +153,11 @@ struct ShowKeyboardArg { class String { public: - String(int size) { + String(s32 size) { bufsize = size; strBuf = nullptr; } - String(int size, char* buf) { + String(s32 size, char* buf) { bufsize = size; strBuf = buf; } @@ -170,7 +170,7 @@ class String { private: char* strBuf; - int bufsize; + s32 bufsize; }; struct UserWord; // TODO contents missing @@ -178,30 +178,30 @@ struct KbdConfig; // TODO contents missing struct CustomizedDictionarySet { void* buffer; // 0x1000-byte aligned buffer. - int bufferSize; // 0x1000-byte aligned buffer size. + s32 bufferSize; // 0x1000-byte aligned buffer size. u64 entries[0x18]; u16 totalEntries; }; -typedef TextCheckResult (*TextCheckCb)(void*, ulong*, String*); +#if NN_SDK_VER >= NN_MAKE_VER(8, 0, 0) +using TextCheckCb = TextCheckResult (*)(void*, u32*, String*); +#else +using TextCheckCb = TextCheckResult (*)(void*, u64*, String*); +#endif -int ConvertUtf8ToUtf16(void*, int, const char*, int); -int ConvertUtf8ToUtf16(void*, int, const char*); -int GetLengthOfConvertedStringUtf8ToUtf16(const char*); +s32 ConvertUtf8ToUtf16(void*, s32, const char*, s32); +s32 ConvertUtf8ToUtf16(void*, s32, const char*); +s32 GetLengthOfConvertedStringUtf8ToUtf16(const char*); void MakePresetDefault(KeyboardConfig*); void MakePresetPassword(KeyboardConfig*); void MakePresetUsername(KeyboardConfig*); void MakePresetDownloadCode(KeyboardConfig*); Result GetInteractiveOutStorageCallback(nn::applet::LibraryAppletHandle, String*, const ShowKeyboardArg&); -ulong GetRequiredTextCheckWorkBufferSize(); +size_t GetRequiredTextCheckWorkBufferSize(); void ReadCloseResultAndString(nn::applet::LibraryAppletHandle, CloseResult*, String*); -void CopyInitialStringInfo(ShowKeyboardArg*, int); -void CopyUserDictionaryInfo(ShowKeyboardArg*, int); - -#if NN_SDK_VER >= NN_MAKE_VER(3, 0, 0) -ulong GetRequiredWorkBufferSize(int); -#endif +void CopyInitialStringInfo(ShowKeyboardArg*, s32); +void CopyUserDictionaryInfo(ShowKeyboardArg*, s32); #if NN_SDK_VER >= NN_MAKE_VER(6, 0, 0) void keyboardConfig2kbdConfig(const KeyboardConfig&, KbdConfig*); @@ -216,20 +216,13 @@ Result ShowKeyboard(String*, const ShowKeyboardArg&, Trigger); void InitializeKeyboardConfig(KeyboardConfig*); void MakePreset(KeyboardConfig*, Preset); -ulong GetRequiredWorkBufferSize(bool); - -#if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) && NN_SDK_VER < NN_MAKE_VER(2, 0, 0) -ulong GetRequiredWorkBufferSize(int); -#endif - -#if NN_SDK_VER >= NN_MAKE_VER(3, 0, 0) -ulong GetRequiredWorkBufferSize(); -#endif +size_t GetRequiredWorkBufferSize(bool); -#if NN_SDK_VER < NN_MAKE_VER(2, 0, 0) -ulong GetRequiredStringBufferSize(); +#if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) +size_t GetRequiredWorkBufferSize(s32); #endif +size_t GetRequiredStringBufferSize(); void SetOkText(KeyboardConfig*, const char16_t*); void SetOkTextUtf8(KeyboardConfig*, const char*); void SetLeftOptionalSymbolKey(KeyboardConfig*, char16_t); @@ -244,7 +237,7 @@ void SetGuideText(KeyboardConfig*, const char16_t*); void SetGuideTextUtf8(KeyboardConfig*, const char*); void SetInitialText(ShowKeyboardArg*, const char16_t*); void SetInitialTextUtf8(ShowKeyboardArg*, const char*); -void SetUserWordList(ShowKeyboardArg*, const UserWord*, int); +void SetUserWordList(ShowKeyboardArg*, const UserWord*, s32); #if NN_SDK_VER >= NN_MAKE_VER(6, 0, 0) void SetCustomizedDictionaries(ShowKeyboardArg*, const CustomizedDictionarySet&); @@ -253,7 +246,7 @@ void SetCustomizedDictionaries(ShowKeyboardArg*, const CustomizedDictionarySet&) void SetTextCheckCallback(ShowKeyboardArg*, TextCheckCb); #if NN_SDK_VER < NN_MAKE_VER(4, 0, 0) -nn::applet::ExitReason GetExitReason(); +nn::applet::ExitReason getExitReason(); #endif extern nn::applet::ExitReason g_ExitReason; From c7e3125b41fe2520d9d47b9ae24b4c1d78aa4f97 Mon Sep 17 00:00:00 2001 From: Narr the Reg <5944268+german77@users.noreply.github.com> Date: Mon, 13 Apr 2026 10:55:20 -0600 Subject: [PATCH 3/3] Add LibraryAppletHandle stucture --- include/nn/applet.h | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/include/nn/applet.h b/include/nn/applet.h index db48224..f23456c 100644 --- a/include/nn/applet.h +++ b/include/nn/applet.h @@ -5,6 +5,45 @@ namespace nn::applet { enum class ExitReason { Normal = 0, Canceled = 1, Abnormal = 2, Unexpected = 10 }; -// TODO: Fill members of LibraryAppletHandle. This contains a service ctx -struct LibraryAppletHandle; +enum class AppletId { + None = 0x00, + application = 0x01, + OverlayApplet = 0x02, + SystemAppletMenu = 0x03, + SystemApplication = 0x04, + LibraryAppletAuth = 0x0A, + LibraryAppletCabinet = 0x0B, + LibraryAppletController = 0x0C, + LibraryAppletDataErase = 0x0D, + LibraryAppletError = 0x0E, + LibraryAppletNetConnect = 0x0F, + LibraryAppletPlayerSelect = 0x10, + LibraryAppletSwkbd = 0x11, + LibraryAppletMiiEdit = 0x12, + LibraryAppletWeb = 0x13, + LibraryAppletShop = 0x14, + LibraryAppletPhotoViewer = 0x15, + LibraryAppletSet = 0x16, + LibraryAppletOfflineWeb = 0x17, + LibraryAppletLoginShare = 0x18, + LibraryAppletWifiWebAuth = 0x19, + LibraryAppletMyPage = 0x1A, +}; + +enum class AppletMode { + AllForeground = 0, + Background = 1, + NoUi = 2, + BackgroundIndirect = 3, + AllForegroundInitiallyHidden = 4, +}; + +struct LibraryAppletHandle { + char _filler0[0x18]; + AppletId id; + AppletMode mode; + char _filler20[0x78]; +}; +static_assert(sizeof(LibraryAppletHandle) == 0x98); + } // namespace nn::applet