Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 50 additions & 6 deletions nx/include/switch/nacp.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,29 @@ typedef struct {
u64 memory_size; ///< MemorySize
} NacpApplicationJitConfiguration;

/// ApplicationControlDataCondition
typedef struct {
u8 type[8]; ///< Type
struct {
u8 priority; ///< Priority
u8 reserved_x1[0x7]; ///< Reserved
u16 aoc_index; ///< AocIndex
u8 reserved_xa[0x6]; ///< Reserved
} data[8];
u8 count; ///< Count
} NacpApplicationControlDataCondition;

typedef union {
NacpLanguageEntry lang[16]; ///< Use only if TitlesDataFormat == 0, \ref NacpLanguageEntry
struct {
u16 buffer_size;
u8 buffer[0x2FFE]; ///< Compressed using DEFLATE with wbits = -15
} compressed_data; ///< Use only if TitlesDataFormat == 1, uncompressed data matches NacpLanguageEntry[32]
} NacpLanguageEntryData;

/// ns ApplicationControlProperty
typedef struct {
NacpLanguageEntry lang[16]; ///< \ref NacpLanguageEntry
NacpLanguageEntryData lang_data; ///< \ref NacpLanguageEntryData
u8 isbn[0x25]; ///< Isbn
u8 startup_user_account; ///< StartupUserAccount
u8 user_account_switch_lock; ///< UserAccountSwitchLock
Expand Down Expand Up @@ -60,7 +80,8 @@ typedef struct {
u8 logo_handling; ///< LogoHandling
u8 runtime_add_on_content_install; ///< RuntimeAddOnContentInstall
u8 runtime_parameter_delivery; ///< RuntimeParameterDelivery
u8 reserved_x30f4[0x2]; ///< Reserved
u8 appropriate_age_for_china; ///< AppropriateAgeForChina
u8 reserved_x30f5; ///< Reserved
u8 crash_report; ///< CrashReport
u8 hdcp; ///< Hdcp
u64 pseudo_device_id_seed; ///< SeedForPseudoDeviceId
Expand All @@ -76,19 +97,42 @@ typedef struct {
u64 cache_storage_journal_size; ///< CacheStorageJournalSize
u64 cache_storage_data_and_journal_size_max; ///< CacheStorageDataAndJournalSizeMax
u16 cache_storage_index_max; ///< CacheStorageIndexMax
u8 reserved_x318a[0x6]; ///< Reserved
u8 reserved_x318a; ///< Reserved
u8 runtime_upgrade; ///< RuntimeUpgrade
u32 supporting_limited_applications_licenses; ///< SupportingLimitedApplicationLicenses
u64 play_log_queryable_application_id[0x10]; ///< PlayLogQueryableApplicationId
u8 play_log_query_capability; ///< PlayLogQueryCapability
u8 repair_flag; ///< RepairFlag
u8 program_index; ///< ProgramIndex
u8 required_network_service_license_on_launch; ///< RequiredNetworkServiceLicenseOnLaunchFlag
u32 reserved_x3214; ///< Reserved
u8 application_error_code_prefix; ///< [20.0.0+] ApplicationErrorCodePrefix
u8 titles_data_format; ///< [21.0.0+] TitlesDataFormat
u8 acd_index; ///< [20.0.0+] AcdIndex
u8 apparent_platform; ///< [20.0.0+] ApparentPlatform
NacpNeighborDetectionClientConfiguration neighbor_detection_client_configuration; ///< NeighborDetectionClientConfiguration
NacpApplicationJitConfiguration jit_configuration; ///< JitConfiguration
u8 reserved_x33c0[0xc40]; ///< Reserved
u16 required_addon_contents_set_binary_descriptor[0x20]; ///< RequiredAddOnContentsSetBinaryDescriptor
u8 play_report_permission; ///< PlayReportPermission
u8 crash_screenshot_for_prod; ///< CrashScreenshotForProd
u8 crash_screenshot_for_dev; ///< CrashScreenshotForDev
u8 contents_availability_transition_policy; ///< ContentsAvailabilityTransitionPolicy
u8 supported_language_flag_for_nx_addon; ///< [21.0.0+] SupportedLanguageFlagForNxAddon
u64 accessible_launch_required_version[0x8]; ///< AccessibleLaunchRequiredVersion
NacpApplicationControlDataCondition application_control_data_condition; ///< [20.0.0+] ApplicationControlDataCondition
u8 initial_program_index; ///< [20.0.0+] InitialProgramIndex
u8 reserved_x34d2; ///< Reserved
u32 accessible_program_index_flags; ///< [20.0.0+] AccessibleProgramIndexFlags
u8 album_file_export; ///< [20.0.0+] AlbumFileExport
u8 reserved_x34d9[0x7]; ///< Reserved
u8 save_data_certificate_bytes[0x80]; ///< [20.0.0+] SaveDataCertificateBytes
u8 has_in_game_voice_char; ///< [20.0.0+] HasInGameVoiceChat
u8 reserved_x3561[0x3]; ///< Reserved
u32 supported_extra_addon_content_flag; ///< [20.0.0+] SupportedExtraAddOnContentFlag
u8 has_karaoke_feature; ///< [21.0.0+] HasKaraokeFeature
u8 reserved_x3569[0x697]; ///< Reserved
u8 platform_specific_region[0x400]; ///< [20.0.0+] PlatformSpecificRegion
} 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);

5 changes: 2 additions & 3 deletions nx/source/runtime/nacp.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ Result nacpGetLanguageEntry(NacpStruct* nacp, NacpLanguageEntry** langentry) {
if (R_FAILED(rc))
return rc;

entry = &nacp->lang[g_nacpLanguageTable[Language]];
entry = &nacp->lang_data.lang[g_nacpLanguageTable[Language]];

if (entry->name[0]==0 && entry->author[0]==0) {
for(i=0; i<16; i++) {
entry = &nacp->lang[i];
entry = &nacp->lang_data.lang[i];
if (entry->name[0] || entry->author[0]) break;
}
}
Expand All @@ -76,4 +76,3 @@ Result nacpGetLanguageEntry(NacpStruct* nacp, NacpLanguageEntry** langentry) {

return rc;
}

6 changes: 3 additions & 3 deletions nx/source/services/ns.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,11 +541,11 @@ Result nsGetApplicationDesiredLanguage(NacpStruct *nacp, NacpLanguageEntry **lan

if (R_SUCCEEDED(rc)) {
for (u32 i=0; i<16; i++) {
entry = &nacp->lang[i];
entry = &nacp->lang_data.lang[i];
if (entry->name[0] || entry->author[0]) lang_bitmask |= BIT(i);
}
if (!lang_bitmask) {
*langentry = &nacp->lang[0];
*langentry = &nacp->lang_data.lang[0];
return 0;
}
}
Expand All @@ -554,7 +554,7 @@ Result nsGetApplicationDesiredLanguage(NacpStruct *nacp, NacpLanguageEntry **lan
if (R_SUCCEEDED(rc)) {
if (out > 16) out = 0;
if (lang_bitmask & BIT(out))
*langentry = &nacp->lang[out];
*langentry = &nacp->lang_data.lang[out];
else
rc = MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen);
}
Expand Down