diff --git a/nx/include/switch/nacp.h b/nx/include/switch/nacp.h index 4faffdc4..784581df 100644 --- a/nx/include/switch/nacp.h +++ b/nx/include/switch/nacp.h @@ -77,5 +77,6 @@ typedef struct { } NacpStruct; /// Get the NacpLanguageEntry from the input nacp corresponding to the current system language (this may fallback to other languages when needed). Output langentry is NULL if none found / content of entry is empty. +/// If you're using ns you may want to use \ref nsGetApplicationDesiredLanguage instead. Result nacpGetLanguageEntry(NacpStruct* nacp, NacpLanguageEntry** langentry); diff --git a/nx/include/switch/services/ns.h b/nx/include/switch/services/ns.h index 11ca6784..26252f81 100644 --- a/nx/include/switch/services/ns.h +++ b/nx/include/switch/services/ns.h @@ -280,6 +280,14 @@ Result nsGetContentManagementInterface(Service* srv_out); */ Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size); +/** + * @brief GetApplicationDesiredLanguage. Selects a \ref NacpLanguageEntry to use from the specified \ref NacpStruct. + * @note Uses \ref nsGetReadOnlyApplicationControlDataInterface on [5.1.0+], otherwise IApplicationManagerInterface is used. + * @param[in] nacp \ref NacpStruct + * @param[out] langentry \ref NacpLanguageEntry + */ +Result nsGetApplicationDesiredLanguage(NacpStruct *nacp, NacpLanguageEntry **langentry); + ///@} ///@name IECommerceInterface diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index 3a665891..7dd78433 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -316,6 +316,49 @@ Result nsGetApplicationControlData(NsApplicationControlSource source, u64 applic return rc; } +Result nsGetApplicationDesiredLanguage(NacpStruct *nacp, NacpLanguageEntry **langentry) { + if (nacp==NULL || langentry==NULL) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + + *langentry = NULL; + + NacpLanguageEntry *entry = NULL; + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + u32 cmd_id = 55; + if (hosversionAtLeast(5,1,0)) { + rc = nsGetReadOnlyApplicationControlDataInterface(&srv); + cmd_id = 1; + } + else + srv_ptr = &g_nsAppManSrv; + + u8 lang_bitmask=0, out=0; + + if (R_SUCCEEDED(rc)) { + for (u32 i=0; i<16; i++) { + entry = &nacp->lang[i]; + if (entry->name[0] || entry->author[0]) lang_bitmask |= BIT(i); + } + if (!lang_bitmask) { + *langentry = &nacp->lang[0]; + return 0; + } + } + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, cmd_id, lang_bitmask, out); + if (R_SUCCEEDED(rc)) { + if (out > 16) out = 0; + if (lang_bitmask & BIT(out)) + *langentry = &nacp->lang[out]; + else + rc = MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); + } + + serviceClose(&srv); + return rc; +} + // IECommerceInterface Result nsRequestLinkDevice(AsyncResult *a, AccountUid uid) {