Line 6: |
Line 6: |
| |- | | |- |
| ! System Version || Value | | ! System Version || Value |
| + | |- |
| + | | pre-1.0.0 || <=0x2 |
| |- | | |- |
| | [1.0.0+] || 0x3 | | | [1.0.0+] || 0x3 |
Line 14: |
Line 16: |
| |- | | |- |
| | [8.0.0+] || 0x7 | | | [8.0.0+] || 0x7 |
| + | |- |
| + | | [11.0.0+] || 0x8 |
| |} | | |} |
| | | |
Line 29: |
Line 33: |
| | 0x0 || 0x4 || Size of this ControllerSupportArgPrivate struct. | | | 0x0 || 0x4 || Size of this ControllerSupportArgPrivate struct. |
| |- | | |- |
− | | 0x4 || 0x4 || Size of the storage following this one ([[#ControllerSupportArg]] or [[#ControllerFirmwareUpdateArg]]). | + | | 0x4 || 0x4 || Size of [[#ControllerSupportArg]]. |
| |- | | |- |
| | 0x8 || 0x1 || Flag0 | | | 0x8 || 0x1 || Flag0 |
Line 35: |
Line 39: |
| | 0x9 || 0x1 || Flag1 | | | 0x9 || 0x1 || Flag1 |
| |- | | |- |
− | | 0xA || 0x1 || [[#Type]] | + | | 0xA || 0x1 || [[#ControllerSupportMode]] |
| |- | | |- |
− | | 0xB || 0x1 || <code>nn::hid::system::ControllerSupportCaller</code>. Always zero except with ShowControllerFirmwareUpdateForSystem, which sets this to the input param. | + | | 0xB || 0x1 || [[#ControllerSupportCaller]]. Always zero except with ShowControllerFirmwareUpdateForSystem/ShowControllerKeyRemappingForSystem, which sets this to the input param. |
| |- | | |- |
| | 0xC || 0x4 || Output from [[HID_services#GetSupportedNpadStyleSet|GetSupportedNpadStyleSet]]. With ShowControllerSupportForSystem on pre-3.0.0 this is value 0. | | | 0xC || 0x4 || Output from [[HID_services#GetSupportedNpadStyleSet|GetSupportedNpadStyleSet]]. With ShowControllerSupportForSystem on pre-3.0.0 this is value 0. |
Line 45: |
Line 49: |
| | | |
| == ControllerSupportArg == | | == ControllerSupportArg == |
− | This is "nn::hid::ControllerSupportArg". This is a 0x21C-byte (0x430-byte with version 0x7) struct pushed for input storage. | + | This is "nn::hid::ControllerSupportArg". This is a 0x21C-byte (0x9C-byte with version <=0x2, 0x430-byte with version 0x7) struct pushed for input storage. |
− | | |
− | Layout with the original version:
| |
| | | |
| {| class="wikitable" border="1" | | {| class="wikitable" border="1" |
Line 55: |
Line 57: |
| ! Description | | ! Description |
| |- | | |- |
− | | 0x0 || 0x1 || s8 playerCountMin, must be >=0 and <=4. | + | | 0x0 || 0x1 || s8 playerCountMin (must be >=0 and <=max_supported_players). Older versions assert when invalid, newer versions clamp the used value to a valid range. |
| + | |- |
| + | | 0x1 || 0x1 || s8 playerCountMax (must be >=1 and <=max_supported_players). Older versions assert when invalid, newer versions clamp the used value to a valid range. |
| + | |- |
| + | | 0x2 || 0x1 || u8 enableTakeOverConnection. Disconnects the controllers when not enabled. |
| + | |- |
| + | | 0x3 || 0x1 || u8 enableLeftJustify. |
| |- | | |- |
− | | 0x1 || 0x1 || s8 playerCountMax, must be >=1 and <=4. | + | | 0x4 || 0x1 || u8 enablePermitJoyDual. |
| |- | | |- |
− | | 0x2 || 0x4 || Unknown, copied into state as individual bytes. | + | | 0x5 || 0x1 || u8 enableSingleMode. Enables using a single player in handheld-mode, dual-mode, or single-mode (playerCount* are overridden). Using handheld-mode is not allowed if this is not enabled. |
| |- | | |- |
− | | 0x6 || 0x1 || Enables using the 0x10-bytes at offset 0x7 when non-zero. | + | | 0x6 || 0x1 || u8 enableIdentificationColor. Enables using the identificationColor array when non-zero. |
| |- | | |- |
− | | 0x7 || 0x10 || Unknown, copied into state as individual bytes. | + | | 0x7 || 4*max_supported_players || u8 identificationColor[4]. Array of 4-byte entries for each player, see below for total entries (max controllers). This entry contains 4 u8s, for the RGBA8 color. This controls the color of the UI player box outline. |
| |- | | |- |
− | | 0x17 || 0x1 || Enables using the ExplainText data when non-zero. | + | | 0x7 + 4*max_supported_players || 0x1 || u8 enableExplainText. Enables using the ExplainText data when non-zero. |
| |} | | |} |
| | | |
− | Layout starting with version 0x7:
| + | With both versions, the rest of the struct is an array containing 0x81-byte (0x21-byte with version <=0x2) entries. With version pre-0x7 there's 4 entries allocated, starting with version 0x7 there's 8 entries allocated. This contains the ExplainText string which includes the NUL-terminator. Each entry corresponds to a controller NpadId, starting with NpadId/controller 0. |
| + | |
| + | Regardless of version, the default data for this struct is setup by setting u32 +0 to 0x01010400, u8 +4 to 0x1, with the rest being cleared as needed. sdknso itself only calls the func for this from ShowControllerStrapGuide, since that's the only time sdknso itself writes to ControllerSupportArg besides ExplainText (and is also the only case where the ControllerSupportArg is not user-specified). |
| + | |
| + | == ControllerFirmwareUpdateArg == |
| + | This is "nn::hid::ControllerFirmwareUpdateArg". This is a 4-byte struct pushed for the input storage. The default value of this entire struct is 0. |
| | | |
| {| class="wikitable" border="1" | | {| class="wikitable" border="1" |
Line 76: |
Line 89: |
| ! Description | | ! Description |
| |- | | |- |
− | | 0x0 || 0x28 || ? | + | | 0x0 || 0x1 || u8 enableForceUpdate, non-zero to enable. Default is 0. Forces a firmware update when enabled, without an UI option to skip it. |
| + | |- |
| + | | 0x1 || 0x3 || u8 padding[3]. |
| |} | | |} |
| | | |
− | With both versions, the rest of the struct is an array containing 0x81-byte entries. With the original version there's 4 entries allocated, starting with version 0x7 there's 8 entries allocated. This contains the ExplainText string which includes the NUL-terminator. Each entry corresponds to a controller NpadId, starting with NpadId/controller 0.
| + | == ControllerKeyRemappingArg == |
| + | This is "nn::hid::system::ControllerKeyRemappingArg". This is a 0x10-byte struct. |
| | | |
− | Regardless of version, the default data for this struct is setup by setting u32 +0 to 0x01010400, u8 +4 to 0x1, with the rest being cleared as needed. sdknso itself only calls the func for this from ShowControllerStrapGuide, since that's the only time sdknso itself writes to ControllerSupportArg besides ExplainText (and is also the only case where the ControllerSupportArg is not user-specified).
| + | The defaults for this is all-zero for the first 0xC-bytes. |
− | | |
− | == ControllerFirmwareUpdateArg ==
| |
− | This is "nn::hid::ControllerFirmwareUpdateArg". This is a 4-byte struct pushed for the input storage. The default value of this entire struct is 0.
| |
| | | |
| {| class="wikitable" border="1" | | {| class="wikitable" border="1" |
Line 92: |
Line 105: |
| ! Description | | ! Description |
| |- | | |- |
− | | 0x0 || 0x1 || ? | + | | 0x0 || 0x8 || |
| + | |- |
| + | | 0x8 || 0x4 || |
| |- | | |- |
− | | 0x1 || 0x3 || ? | + | | 0xC || 0x4 || Padding |
| |} | | |} |
| | | |
− | == Type == | + | == ControllerSupportMode == |
| + | This is "nn::hid::system::ControllerSupportMode". |
| + | |
| {| class="wikitable" border="1" | | {| class="wikitable" border="1" |
| |- | | |- |
− | ! Name || Type value || Description | + | ! Value || Description |
| + | |- |
| + | | 0 || ShowControllerSupport |
| |- | | |- |
− | | ShowControllerSupport || 0 || | + | | 1 || [3.0.0+] ShowControllerStrapGuide |
| |- | | |- |
− | | [3.0.0+] ShowControllerStrapGuide || 1 || | + | | 2 || [3.0.0+] ShowControllerFirmwareUpdate |
| |- | | |- |
− | | [3.0.0+] ShowControllerFirmwareUpdate || 2 || | + | | 4 || [11.0.0+] ShowControllerKeyRemappingForSystem |
| |} | | |} |
| | | |
Line 114: |
Line 133: |
| | | |
| ShowControllerFirmwareUpdateForSystem is the same as ShowControllerFirmwareUpdate, except [[#ControllerSupportArgPrivate|Flag1]] is set to 1 and [[#ControllerSupportArgPrivate|ControllerSupportCaller]] is set to the input param. | | ShowControllerFirmwareUpdateForSystem is the same as ShowControllerFirmwareUpdate, except [[#ControllerSupportArgPrivate|Flag1]] is set to 1 and [[#ControllerSupportArgPrivate|ControllerSupportCaller]] is set to the input param. |
| + | |
| + | ShowControllerSupportCore will assert if the mode is ShowControllerFirmwareUpdate, and ShowControllerFirmwareUpdateCore will assert if the mode is not ShowControllerFirmwareUpdate. |
| + | |
| + | ShowControllerSupport seems to only display the applet UI when doing so is actually needed?(This doesn't apply to the ForSystem version) |
| + | |
| + | == ControllerSupportCaller == |
| + | This is "nn::hid::system::ControllerSupportCaller". |
| + | |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Value || Description |
| + | |- |
| + | | 0 || Application |
| + | |- |
| + | | 1 || Skips the firmware-update confirmation dialog. This has the same affect as using the controller-update option from qlaunch System Settings. |
| + | |} |
| | | |
| == ControllerSupportResultInfo == | | == ControllerSupportResultInfo == |
| This is "nn::hid::ControllerSupportResultInfo". This is a 8-byte struct. | | This is "nn::hid::ControllerSupportResultInfo". This is a 8-byte struct. |
| + | |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| + | |- |
| + | | 0x0 || 0x1 || s8 playerCount. |
| + | |- |
| + | | 0x1 || 0x3 || u8 padding[3]. |
| + | |- |
| + | | 0x4 || 0x4 || u32 selectedId, NpadId. |
| + | |} |
| | | |
| == Usage == | | == Usage == |
− | User-processes should push a common arguments struct, an [[#ControllerSupportArgPrivate]], then [[#ControllerSupportArg]] or [[#ControllerFirmwareUpdateArg]]. | + | User-processes should push a common arguments struct, an [[#ControllerSupportArgPrivate]], then [[#ControllerSupportArg]] / [[#ControllerFirmwareUpdateArg]] / [[#ControllerKeyRemappingArg]]. |
| | | |
| On success, an output storage should be popped, with size 0xC being used to read from there (sdknso ignores the actual storage size). When [[#ControllerSupportArg]] was previously used, the first 8-bytes are copied to the output [[#ControllerSupportResultInfo]] (which the user can ignore), otherwise it's ignored. The remaining u32 determines the Result: | | On success, an output storage should be popped, with size 0xC being used to read from there (sdknso ignores the actual storage size). When [[#ControllerSupportArg]] was previously used, the first 8-bytes are copied to the output [[#ControllerSupportResultInfo]] (which the user can ignore), otherwise it's ignored. The remaining u32 determines the Result: |