HID Shared Memory: Difference between revisions

No edit summary
(34 intermediate revisions by 4 users not shown)
Line 1: Line 1:
HID shared memory is a 0x40000 byte read-only segment of memory shared between applications for input. The segment contains structures for most if not all input methods available to applications.
HID shared memory is a 0x40000 byte read-only segment of memory shared between applications for input. The segment contains structures for most if not all input methods available to applications.
In sdknso this is "nn::hid::detail::SharedMemoryFormat".


= Memory Map =
= Memory Map =
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x400
| 0x400
| Unknown, Header?
| [[#DebugPad]]
|-
|-
| 0x400
| 0x400
| 0x3000
| 0x3000
| Capacitive Touchscreen
| [[#TouchScreen]]
|-
|-
| 0x3400
| 0x3400
| 0x400
| 0x400
| Mouse
| [[#Mouse]]
|-
|-
| 0x3800
| 0x3800
| 0x400
| 0x400
| Keyboard
| [[#Keyboard]]
|-
|-
| 0x3C00
| 0x3C00
| 0x400
| 0x1000 (0x400 * 0x04)
| Unknown, header and 17 entries
| [1.0.0-9.2.0] [[#BasicXpad]]
|-
|-
| 0x4000
| 0x3C00
| 0x400
|  
| Unknown, header and 17 entries
| [10.0.0+] Digitizer
|-
| 0x4400
| 0x400
| Unknown, header and 17 entries
|-
| 0x4800
| 0x400
| Unknown, header and 17 entries
|-
|-
| 0x4C00
| 0x4C00
| 0x200
| 0x200
| Unknown, header which says it has 17 entries, but the max entry index is 0
| [[#HomeButton]]
|-
|-
| 0x4E00
| 0x4E00
| 0x200
| 0x200
| Unknown, header which says it has 17 entries, but the max entry index is 0
| [[#SleepButton]]
|-
|-
| 0x5000
| 0x5000
| 0x200
| 0x200
| Unknown, header which says it has 17 entries, but the max entry index is 0
| [[#CaptureButton]]
|-
|-
| 0x5200
| 0x5200
| 0x80*0x10
| 0x800 (0x80 * 0x10)
| Unknown, 16 structures with a header and 2 entries each
| [[#InputDetector]]
|-
|-
| 0x5A00
| 0x5A00
| 0x4000
| 0x4000 (0x400 * 0x10)
| Controller Serials?
| [1.0.0-4.1.0] [[#UniquePad]]
|-
|-
| 0x9A00
| 0x9A00
| 0x32000
| 0x32000 (0x5000 * 0x0A)
| Controllers
| [[#Npad]]
|-
|-
| 0x3BA00
| 0x3BA00
| 0x4600
| 0x800
| Unknown
| [[#Gesture]]
|-
|-
| 0x3C200
| 0x20
| [5.0.0+] [[#ConsoleSixAxisSensor]]
|}
|}


== Capacitive Touchscreen ==
== DebugPad ==
 
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x28
| 0x20
| Touch Header
| [[#DebugPadHeader]]
|-
| 0x28
| 0x298 * 17
| Touch Entries
|-
|-
| 0x20
| 0x28 * 17
| Array of [[#DebugPadState]]
|}
|}


=== Touch Header ===
=== DebugPadHeader ===
 
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x8
| Timestamp in ticks?
| Timestamp in ticks
|-
|-
| 0x8
| 0x8
| 0x8
| 0x8
| Number of Entries, always 17
| Number of Entries (always 17)
|-
|-
| 0x10
| 0x10
| 0x8
| 0x8
| Latest Entry Index
| Latest Entry Index
|-
|-
| 0x18
| 0x18
| 0x8
| 0x8
| Maximum Entry Index, always 16
| Maximum Entry Index (always 16)
|}
 
=== DebugPadState ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
|-
| 0x20
| 0x0
| 0x8
| 0x8
| Timestamp in samples
| Timestamp in samples (global)
|-
|-
| 0x8
| 0x20
|
|}
|}


=== Touch Entry ===
== TouchScreen ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x20
| [[#TouchScreenHeader]]
|-
| 0x20
| 0x298 * 17
| Array of [[#TouchScreenState]]
|}


=== TouchScreenHeader ===
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x10
| 0x8
| Touch Entry Header
| Timestamp in ticks
|-
| 0x8
| 0x8
| Number of Entries (always 17)
|-
|-
| 0x10
| 0x10
| 0x28 * 16
| 0x8
| Touch Data
| Latest Entry Index
|-
|-
| 0x18
| 0x8
| Maximum Entry Index (always 16)
|}
|}


==== Touch Structure Header ====
=== TouchScreenState ===
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x8
| Timestamp in samples (global)
|-
| 0x8
| 0x8
| Timestamp in samples
| Timestamp in samples
|-
|-
| 0x8
| 0x10
| 0x8
| 0x8
| Number of Touches
| Touch count
|-
|-
| 0x18
| 0x28 * 16
| [[#TouchScreenStateData]]
|}
|}


==== Touch Data Entry ====
==== TouchScreenStateData ====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x8
| Timestamp in samples
| Timestamp in samples
|-
|-
| 0x8
| 0x8
| 0x4
| 0x4
| Padding
| Padding
|-
|-
| 0xC
| 0xC
Line 173: Line 206:
| Touch Index
| Touch Index
|-
|-
| 0x10
| 0x10
| 0x4
| 0x4
| Touch X
| Touch X
|-
|-
| 0x14
| 0x14
| 0x4
| 0x4
| Touch Y
| Touch Y
|-
|-
| 0x18
| 0x18
| 0x4
| 0x4
| Touch Diameter X
| Touch Diameter X
|-
|-
| 0x1C
| 0x1C
| 0x4
| 0x4
| Touch Diameter Y
| Touch Diameter Y
|-
|-
| 0x20
| 0x20
| 0x4
| 0x4
| Angle
| Angle
|-
| 0x24
| 0x4
| Padding
|-
|-
| 0x24
| 0x4
| Padding
|}
|}


== Mouse ==
== Mouse ==
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x20
| 0x20
| Mouse Header
| [[#MouseHeader]]
|-
|-
| 0x20
| 0x20
| 0x30 * 17
| 0x30 * 17
| Mouse Entries
| Array of [[#MouseState]]
|}
 
=== MouseHeader ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in ticks
|-
|-
| 0x8
| 0x8
| Number of Entries (always 17)
|-
| 0x10
| 0x8
| Latest Entry Index
|-
| 0x18
| 0x8
| Maximum Entry Index (always 16)
|}
|}


=== Mouse Header ===
=== MouseState ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in samples (global)
|-
| 0x8
| 0x8
| Timestamp in samples
|-
| 0x10
| 0x4
| Mouse X
|-
| 0x14
| 0x4
| Mouse Y
|-
| 0x18
| 0x4
| Mouse X Change
|-
| 0x1C
| 0x4
| Mouse Y Change
|-
| 0x20
| 0x4
| Scroll Change Y
|-
| 0x24
| 0x4
| Scroll Change X
|-
| 0x28
| 0x8
| Mouse Buttons
|}


== Keyboard ==
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x20
| Timestamp in ticks?
| [[#KeyboardHeader]]
|-
|-
| 0x8
| 0x20
| 0x8
| 0x38 * 17
| Number of Entries, always 17
| Array of [[#KeyboardState]]
|}
 
=== KeyboardHeader ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in ticks
|-
|-
| 0x10
| 0x8
| 0x8
| 0x8
| Number of Entries (always 17)
|-
| 0x10
| 0x8
| Latest Entry Index
| Latest Entry Index
|-
|-
| 0x18
| 0x18
| 0x8
| 0x8
| Maximum Entry Index, always 16
| Maximum Entry Index (always 16)
|}
 
=== KeyboardState ===
{| class="wikitable" border="1"
|-
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in samples (global)
|-
| 0x8
| 0x8
| Timestamp in samples
|-
| 0x10
| 0x8
| Modifier Mask
|-
| 0x18
| 0x20
| Keys Down, each key gets one bit based on the HID keyboard scan code (F1 is 0x3A, bit 0x3A is set)
|}
|}


=== Mouse Entry ===
== BasicXpad ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x20
| [[#BasicXpadHeader]]
|-
| 0x20
| 0x28 * 17
| Array of [[#BasicXpadState]]
|}


=== BasicXpadHeader ===
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x8
| Timestamp in samples
| Timestamp in ticks
|-
| 0x8
| 0x8
| Number of Entries (always 17)
|-
| 0x10
| 0x8
| Latest Entry Index
|-
| 0x18
| 0x8
| Maximum Entry Index (always 16)
|}
 
=== BasicXpadState ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in samples (global)
|-
|-
| 0x8
| 0x8
| 0x8
| 0x20
| Timestamp in samples again?
|  
|}
 
== HomeButton ==
{| class="wikitable" border="1"
|-
|-
| 0x10
! Offset
| 0x4
! Size
| Mouse X
! Description
|-
|-
| 0x14
| 0x0
| 0x4
| 0x20
| Mouse Y
| [[#HomeButtonHeader]]
|-
|-
| 0x18
| 0x20
| 0x4
| 0x18 * 17
| Mouse X Change
| Array of [[#HomeButtonState]]
|}
 
=== HomeButtonHeader ===
{| class="wikitable" border="1"
|-
|-
| 0x1C
! Offset
| 0x4
! Size
| Mouse Y Change
! Description
|-
|-
| 0x20
| 0x0
| 0x4
| 0x8
| Scroll Change Y
| Timestamp in ticks
|-
|-
| 0x24
| 0x8
| 0x4
| 0x8
| Scroll Change X?
| Number of Entries (always 17)
|-
|-
| 0x28
| 0x10
| 0x8
| 0x8
| Mouse Buttons
| Latest Entry Index
|-
|-
| 0x18
| 0x8
| Maximum Entry Index (always 16)
|}
|}


=== HomeButtonState ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in samples (global)
|-
| 0x8
| 0x10
|
|}


== Keyboard ==
== SleepButton ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x20
| [[#SleepButtonHeader]]
|-
| 0x20
| 0x18 * 17
| Array of [[#SleepButtonState]]
|}


=== SleepButtonHeader ===
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
| 0x0
| 0x8
| Timestamp in ticks
|-
| 0x8
| 0x8
| Number of Entries (always 17)
|-
| 0x10
| 0x8
| Latest Entry Index
|-
| 0x18
| 0x8
| Maximum Entry Index (always 16)
|}
 
=== SleepButtonState ===
{| class="wikitable" border="1"
|-
|-
| 0x0
! Offset
| 0x20
! Size
| Keyboard Header
! Description
|-
|-
| 0x20
| 0x0
| 0x30 * 17
| 0x8
| Keyboard Entries
| Timestamp in samples (global)
|-
|-
| 0x8
| 0x10
|
|}
|}


=== Keyboard Header ===
== CaptureButton ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x20
| [[#CaptureButtonHeader]]
|-
| 0x20
| 0x18 * 17
| Array of [[#CaptureButtonState]]
|}


=== CaptureButtonHeader ===
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x8
| Timestamp in ticks?
| Timestamp in ticks
|-
|-
| 0x8
| 0x8
| 0x8
| 0x8
| Number of Entries, always 17
| Number of Entries (always 17)
|-
|-
| 0x10
| 0x10
| 0x8
| 0x8
| Latest Entry Index
| Latest Entry Index
|-
|-
| 0x18
| 0x18
| 0x8
| 0x8
| Maximum Entry Index, always 16
| Maximum Entry Index (always 16)
|}
 
=== CaptureButtonState ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in samples (global)
|-
|-
| 0x8
| 0x10
|
|}
|}


=== Keyboard Entry ===
== InputDetector ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x20
| [[#InputDetectorHeader]]
|-
| 0x20
| 0x18 * 2
| Array of [[#InputDetectorState]]
|}


=== InputDetectorHeader ===
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x8
| Timestamp in samples
| Timestamp in ticks
|-
| 0x8
| 0x8
| Number of Entries (always 17)
|-
| 0x10
| 0x8
| Latest Entry Index
|-
| 0x18
| 0x8
| Maximum Entry Index (always 16)
|}
 
=== InputDetectorState ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in samples (global)
|-
|-
| 0x8
| 0x8
| 0x8
| 0x10
| Timestamp in samples again?
|  
|}
 
== UniquePad ==
This section contains a series of 16 structures 0x400 bytes large.
 
[5.0.0+] This section has been removed from SharedMemoryFormat. [[#UniquePad]] is now a specialization of [[#Npad]].
 
{| class="wikitable" border="1"
|-
|-
| 0x10
! Offset
| 0x8
! Size
| Modifier Mask
! Description
|-
|-
| 0x18
| 0x0
| 0x20
| 0x80
| Keys Down, each key gets one bit based on the HID keyboard scan code (F1 is 0x3A, bit 0x3A is set)
| [[#UniquePadConfig]]
|-
|-
| 0x80
| 0x70 * 2
| Array of [[#AnalogStickCalibration]]
|}
|}


== Controller Serials? ==
=== UniquePadConfig ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x20
| [[#UniquePadConfigHeader]]
|-
| 0x20
| 0x30 * 2
| Array of [[#UniquePadConfigState]]
|}


This section contains a series of 16 structures 0x400 bytes large.
==== UniquePadConfigHeader ====
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in ticks
|-
| 0x8
| 0x8
| Number of Entries (always 17)
|-
| 0x10
| 0x8
| Latest Entry Index
|-
| 0x18
| 0x8
| Maximum Entry Index (always 16)
|}


==== UniquePadConfigState ====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x30
| 0x0
| 0xE
| 0x8
| Controller Serial
| Timestamp in samples (global)
|-
|-
| 0x60
| 0x8
| 0xE
| 0x8
| Controller Serial
|  
|-
|-
| 0x10
| 0x20
| Controller Serial
|}
|}


== Controllers ==
=== AnalogStickCalibration ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x20
| [[#AnalogStickCalibrationHeader]]
|-
| 0x20
| 0x28 * 2
| Array of [[#AnalogStickCalibrationState]]
|}


This section contains a series of 10 0x5000 byte structures describing each available controller.
==== AnalogStickCalibrationHeader ====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Controller Index
! Offset
!   Description
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in ticks
|-
| 0x8
| 0x8
| Number of Entries (always 17)
|-
|-
| 0 to 7
| 0x10
| Players 1 to 8
| 0x8
| Latest Entry Index
|-
| 0x18
| 0x8
| Maximum Entry Index (always 16)
|}
 
==== AnalogStickCalibrationState ====
{| class="wikitable" border="1"
|-
|-
| 8
! Offset
| Handheld Mode
! Size
! Description
|-
|-
| 9
| 0x0
| Unknown
| 0x8
| Timestamp in samples (global)
|-
|-
| 0x8
| 0x28
|
|}
|}


=== Controller ===
== Npad ==
This section contains a series of 10 0x5000 byte structures describing each available controller.
 
{| class="wikitable" border="1"
|-
! Index
! Description
|-
| 0 to 7
| Players 1 to 8
|-
| 8
| Handheld Mode
|-
| 9
| Other
|}


=== NpadState ===
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
| 0x0
| 0x28
| [[#NpadStateHeader]]
|-
| 0x28
| 0x20
| NpadFullKeyHeader
|-
| 0x48
| 0x30 * 17
| Array of NpadFullKeyState
|-
| 0x378
| 0x20
| [[#NpadHandheldHeader]]
|-
| 0x398
| 0x30 * 17
| Array of [[#NpadHandheldState]]
|-
|-
| 0x0
| 0x6C8
| 0x28
| 0x20
| Controller Header
| NpadJoyDualHeader
|-
|-
| 0x28
| 0x6E8
| 0x20 header + 0x30 * 17
| 0x30 * 17
| Controller Pro Controller State
| Array of NpadJoyDualState
|-
|-
| 0x378
| 0xA18
| 0x20 header + 0x30 * 17
| 0x20
| Controller Handheld Joined State
| NpadJoyLeftHeader
|-
|-
| 0x6C8
| 0xA38
| 0x20 header + 0x30 * 17
| 0x30 * 17
| Controller Joined State (Lone Joy-Con or Pair of Joy-Con)
| Array of NpadJoyLeftState
|-
|-
| 0xA18
| 0xD68
| 0x20 header + 0x30 * 17
| 0x20
| Controller Left State (Vertical Controls w/ Joy-Con Half)
| NpadJoyRightHeader
|-
|-
| 0xD68
| 0xD88
| 0x20 header + 0x30 * 17
| 0x30 * 17
| Controller Right State (Vertical Controls w/ Joy-Con Half)
| Array of NpadJoyRightState
|-
|-
| 0x10B8
| 0x10B8
| 0x20 header + 0x30 * 17
| 0x20
| Controller Main State (No Analog Sticks)
| NpadPalmaHeader
|-
| 0x12B8
| 0x30 * 17
| Array of NpadPalmaState
|-
|-
| 0x1408
| 0x1408
| 0x20 header + 0x30 * 17
| 0x20
| Controller Main State
| NpadSystemExtHeader
|-
| 0x1428
| 0x30 * 17
| Array of NpadSystemExtState
|-
|-
| 0x1758
| 0x1758
| ?
| 0x20
| SixAxisSensor Pro Controller State
| NpadSixAxisSensorFullKeyHeader
|-
| 0x1778
| 0x68 * 17
| Array of NpadSixAxisSensorFullKeyState
|-
|-
| 0x1E60
| 0x1E60
| ?
| 0x20
| SixAxisSensor Handheld State
| NpadSixAxisSensorHandheldHeader
|-
|-
| 0x2578
| 0x1E80
| ?
| 0x68 * 17
| SixAxisSensor Pair Left State
| Array of NpadSixAxisSensorHandheldState
|-
|-
| 0x2C80
| 0x2568
| ?
| 0x20
| SixAxisSensor Pair Right State
| NpadSixAxisSensorJoyLeftDualHeader
|-
| 0x2588
| 0x68 * 17
| Array of NpadSixAxisSensorJoyLeftDualState
|-
| 0x2C70
| 0x20
| NpadSixAxisSensorJoyRightDualHeader
|-
| 0x2C90
| 0x68 * 17
| Array of NpadSixAxisSensorJoyRightDualState
|-
|-
| 0x3378
| 0x3378
| ?
| 0x20
| SixAxisSensor Single Left State
| NpadSixAxisSensorJoyLeftHeader
|-
| 0x3398
| 0x68 * 17
| Array of NpadSixAxisSensorJoyLeftState
|-
|-
| 0x3A80
| 0x3A80
| ?
| 0x20
| SixAxisSensor Single Right State
| NpadSixAxisSensorJoyRightHeader
|-
| 0x3AA0
| 0x68 * 17
| Array of NpadSixAxisSensorJoyRightState
|-
| 0x4188
| 0x4
| [[HID_services#DeviceType|DeviceType]]
|-
| 0x418C
| 0x4
| Padding
|-
|-
| 0x41D0
| 0x4190
| 0x10
| 0x8
| Controller MAC
| [[#NpadSystemProperties]]
|-
| 0x4198
| 0x4
| [[#NpadSystemButtonProperties]]
|-
| 0x419C
| 0x4
| BatteryIndex0 state (must be 0-4)
|-
| 0x41A0
| 0x4
| BatteryIndex1 state (must be 0-4)
|-
| 0x41A4
| 0x4
| BatteryIndex2 state (must be 0-4)
|-
| 0x41A8
| 0x20
| NfcXcdDeviceHandleHeader
|-
| 0x41C8
| 0x20 * 2
| Array of NfcXcdDeviceHandleState
|-
| 0x4208
| 0x8
| Mutex
|-
|-
| 0x41F0
| 0x4248
| 0x10
| 0x20
| Controller MAC
| NpadGcTriggerHeader
|-
|-
| 0x4268
| 0x18 * 17
| Array of NpadGcTriggerState
|}
|}


==== Controller Header ====
==== NpadStateHeader ====
 
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x4
| 0x4
| Status, bit0 Pro Controller/HID controller, bit1 wired for handheld, bit2 pair, bit3 left, bit4 right
| Status, bit0 Pro Controller/HID controller, bit1 wired for handheld, bit2 pair, bit3 left, bit4 right
Line 520: Line 1,023:
| 0x4
| 0x4
| RGBA Button Color (left Joy-Con)
| RGBA Button Color (left Joy-Con)
|-
|}
|}


==== Controller State Header ====
==== NpadHandheldHeader ====
 
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x8
| Timestamp in ticks?
| Timestamp in ticks
|-
|-
| 0x8
| 0x8
| 0x8
| 0x8
| Number of entries, always 17
| Number of entries (always 17)
|-
|-
| 0x10
| 0x10
Line 545: Line 1,046:
| 0x18
| 0x18
| 0x8
| 0x8
| Maximum Entry Index, always 16
| Maximum Entry Index (always 16)
|-
|}
|}


==== Controller State ====
==== NpadHandheldState ====
 
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x8
| Timestamp in samples
| Timestamp in samples (global)
|-
|-
| 0x8
| 0x8
| 0x8
| 0x8
| Timestamp in samples again
| Timestamp in samples
|-
|-
| 0x10
| 0x10
| 0x8
| 0x8
| Button State
| [[#NpadButton]]
|-
|-
| 0x18
| 0x18
Line 588: Line 1,087:
| 0x8
| 0x8
| Controller State (bit0 connected, bit1 wired)
| Controller State (bit0 connected, bit1 wired)
|-
|}
|}


===== Button State =====
===== NpadButton =====
This is the u64 bitmask for "nn::hid::NpadButton".


{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Bit
! Bit
!   Button
! Button
|-
|-
| 0
| 0
Line 675: Line 1,174:
| 25
| 25
| SR
| SR
|}
===== NpadSixAxisSensorHandheldHeader =====
{| class="wikitable" border="1"
|-
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in ticks
|-
| 0x8
| 0x8
| Number of entries (always 17)
|-
| 0x10
| 0x8
| Latest Entry Index
|-
| 0x18
| 0x8
| Maximum Entry Index (up to 16)
|}
|}


===== SixAxisSensor State Header =====
===== NpadSixAxisSensorHandheldState =====
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in samples (global)
|-
| 0x8
| 0x8
| Unknown
|-
| 0x10
| 0x8
| Timestamp in samples
|-
| 0x1C
| 0x4 * 3
| Accelerometer data as 3 floats
|-
| 0x24
| 0x4 * 3
| Gyroscope data as 3 floats
|-
| 0x30
| 0x4 * 3
| Unknown sensor data as 3 floats
|-
| 0x3C
| 0x4 * 9
| Orientation basis as 3x3 matrix of floats
|-
| 0x60
| 0x8
| Unknown, always 1
|}


Official sw copies the data from offset 0x8 size 0x60 to the final output state.
==== NpadSystemProperties ====
{| class="wikitable" border="1"
|-
! Bit
! Description
|-
| 0
| PowerInfo0 isCharging
|-
| 1
| PowerInfo1 isCharging
|-
| 2
| PowerInfo2 isCharging
|-
| 3
| PowerInfo0 powerConnected
|-
| 4
| PowerInfo1 powerConnected
|-
| 5
| PowerInfo2 powerConnected
|-
| 6-8
| Unused
|-
| 9
| UnsupportedButtonPressed_NpadSystem
|-
| 10
| UnsupportedButtonPressed_NpadSystemExt
|-
| 11
| AbxyButtonOriented
|-
| 12
| SlSrButtonOriented
|-
| 13
| [4.0.0+] PlusButtonCapability
|-
| 14
| [4.0.0+] MinusButtonCapability
|-
| 15
| [8.0.0+] DirectionalButtonsSupported
|-
| 16-63
| Unused
|}
==== NpadSystemButtonProperties ====
{| class="wikitable" border="1"
|-
! Bit
! Description
|-
| 0
| UnintendedHomeButtonInputProtectionEnabled (if cleared)
|}
== Gesture ==
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x20
| [[#GestureHeader]]
|-
| 0x20
| 0x68 * 17
| Array of [[#GestureState]]
|}
=== GestureHeader ===
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x8
| 0x8
| Timestamp in ticks?
| Timestamp in ticks
|-
|-
| 0x8
| 0x8
| 0x8
| 0x8
| Number of entries, always 17
| Number of Entries (always 17)
|-
|-
| 0x10
| 0x10
Line 700: Line 1,341:
| 0x18
| 0x18
| 0x8
| 0x8
| ?
| Maximum Entry Index (always 16)
|}
 
=== GestureState ===
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x8
| Timestamp in samples (global)
|-
|-
| 0x8
| 0x60
|
|}
|}


 
== ConsoleSixAxisSensor ==
===== SixAxisSensor State Entry =====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
Line 717: Line 1,372:
|-
|-
| 0x8
| 0x8
| 0x60
| 0x1
| The actual state data.
| IsSevenSixAxisSensorAtRest
|-
| 0x9
| 0x3
| Padding
|-
| 0xC
| 0x4
| VerticalizationError
|-
| 0x10
| 0xC
| GyroBias
|-
| 0x1C
| 0x4
| Padding
|}
|}
Official sw copies the data from offset 0x8 size 0x60 to the final output state.