HID Shared Memory: Difference between revisions

No edit summary
Line 2: Line 2:


= 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
| 0x400
| Unknown, header and 17 entries
| BasicXpad
|-
|-
| 0x4000
| 0x4000
Line 43: Line 42:
| 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
| Unknown, 16 structures with a header and 2 entries each
| InputDetector
|-
|-
| 0x5A00
| 0x5A00
Line 63: Line 62:
| 0x9A00
| 0x9A00
| 0x32000
| 0x32000
| Controllers
| Npad
|-
|-
| 0x3BA00
| 0x3BA00
| 0x4600
| 0x4600
| Unknown
| Gesture
|-
|-
| 0x3C200
| 0x3C200
| ?
| ?
| [5.0.0+] SevenSixAxisSensor
| [5.0.0+] ConsoleSixAxisSensor
|-
|}
|}


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


=== Touch Header ===
=== TouchScreenHeader ===
 
{| 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
|-
| 0x20
| 0x8
| Timestamp in samples
|-
|-
| 0x20
| 0x8
| Timestamp in samples
|}
|}


=== Touch Entry ===
=== TouchScreenState ===
 
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x10
| 0x10
| Touch Entry Header
| [[#TouchScreenStateHeader]]
|-
| 0x10
| 0x28 * 16
| Touch Data
|-
|-
| 0x10
| 0x28 * 16
| [[#TouchScreenStateData]]
|}
|}


==== Touch Structure Header ====
==== TouchScreenStateHeader ====
{| 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
| 0x8
| 0x8
| Number of Touches
| Touch count
|-
|}
|}


==== 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 177: Line 168:
| 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]]
|-
|}
|}


=== Mouse Header ===
=== MouseHeader ===
 
{| 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
|-
|}
|}


=== Mouse Entry ===
=== MouseState ===
 
{| 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
| 0x8
| 0x8
| Timestamp in samples again?
| Timestamp in samples again?
|-
|-
| 0x10
| 0x10
| 0x4
| 0x4
| Mouse X
| Mouse X
|-
|-
| 0x14
| 0x14
| 0x4
| 0x4
| Mouse Y
| Mouse Y
|-
|-
| 0x18
| 0x18
| 0x4
| 0x4
| Mouse X Change
| Mouse X Change
|-
|-
| 0x1C
| 0x1C
| 0x4
| 0x4
| Mouse Y Change
| Mouse Y Change
|-
|-
| 0x20
| 0x20
| 0x4
| 0x4
| Scroll Change Y
| Scroll Change Y
|-
|-
| 0x24
| 0x24
| 0x4
| 0x4
| Scroll Change X?
| Scroll Change X
|-
| 0x28
| 0x8
| Mouse Buttons
|-
|-
| 0x28
| 0x8
| Mouse Buttons
|}
|}


== Keyboard ==
== Keyboard ==
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
| 0x20
| 0x20
| Keyboard Header
| [[#KeyboardHeader]]
|-
|-
| 0x20
| 0x20
| 0x38 * 17
| 0x38 * 17
| Keyboard Entries
| Array of [[#KeyboardState]]
|-
|}
|}


=== Keyboard Header ===
=== KeyboardHeader ===
 
{| 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
|-
|}
|}


=== Keyboard Entry ===
=== KeyboardState ===
 
{| 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
| 0x8
| 0x8
| Timestamp in samples again?
| Timestamp in samples again?
|-
|-
| 0x10
| 0x10
| 0x8
| 0x8
| Modifier Mask
| 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)
|-
|-
| 0x18
| 0x20
| Keys Down, each key gets one bit based on the HID keyboard scan code (F1 is 0x3A, bit 0x3A is set)
|}
|}


== Controller Serials? ==
== Controller Serials? ==
This section contains a series of 16 structures 0x400 bytes large.
This section contains a series of 16 structures 0x400 bytes large.


Line 384: Line 360:
|}
|}


== Controllers ==
== Npad ==
This section contains a series of 10 0x5000 byte structures describing each available controller.


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


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


The battery state must be 0-4.
==== NpadInternalStateHeader ====
 
==== Flags ====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Bit
! Offset
!   Description
! Size
|-
! Description
| 0
| PowerInfo0 isCharging
|-
|-
| 1
| 0x0
| 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
|}
 
==== Flags2 ====
Bit0: clear = UnintendedHomeButtonInputProtectionEnabled.
 
==== Controller Header ====
 
{| class="wikitable" border="1"
|-
!  Offset
!  Size in bytes
!  Description
|-
| 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 609: Line 580:
| 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
Line 635: Line 604:
| 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
Line 656: Line 623:
| 0x10
| 0x10
| 0x8
| 0x8
| Button State
| [[#Button State]]
|-
|-
| 0x18
| 0x18
Line 677: Line 644:
| 0x8
| 0x8
| Controller State (bit0 connected, bit1 wired)
| Controller State (bit0 connected, bit1 wired)
|-
|}
|}


===== Button State =====
===== Button State =====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Bit
! Bit
!   Button
! Button
|-
|-
| 0
| 0
Line 764: Line 729:
| 25
| 25
| SR
| SR
|-
|}
|}


===== SixAxisSensor State Header =====
===== NpadSixAxisSensorHandheldHeader =====
 
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
Line 790: Line 753:
| 0x8
| 0x8
| Maximum Entry Index, up to 16
| Maximum Entry Index, up to 16
|-
|}
|}


===== SixAxisSensor State Entry =====
===== NpadSixAxisSensorHandheldState =====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
!   Offset
! Offset
!   Size in bytes
! Size
!   Description
! Description
|-
|-
| 0x0
| 0x0
Line 834: Line 796:


Official sw copies the data from offset 0x8 size 0x60 to the final output state.
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)
|}