Repository navigation
The Joy-Con 2's mouse sensor and pointer, and the Joy-Con 2 npad styles (after #1363, issue #1267) - #1426
Closed
JakePre wants to merge 4 commits into
Closed
The Joy-Con 2's mouse sensor and pointer, and the Joy-Con 2 npad styles (after #1363, issue #1267)#1426JakePre wants to merge 4 commits into
JakePre wants to merge 4 commits into
Conversation
3 tasks done
JakePre
force-pushed
the
switch2-pr4-mouse
branch
4 times, most recently
from
November 7, 2026 19:26
ea0763f to
d8011bc
Compare
…troller 2): an off-by-default setting, pairing by Sync during the game, motion, and Home through the hold-to-quit prompt (issue seedds#1267) macOS lists these controllers neither as GameController nor as HID devices: they are Bluetooth LE devices with Nintendo's own GATT service, and a Joy-Con 2 forgets a connection the moment it drops unless it is bonded to the host. switch2_proto.h is the protocol in pure C (advertisement and what the host does with it, command framing, bonding, the input report, stick calibration, the motion maps; tests/t_switch2.c, 61 checks on recorded reports and replies). pad_switch2_apple.m is one CoreBluetooth transport for the Mac and iOS front ends, as haptics_apple.m is; the front end gives each pad a player slot through dm_switch2_front. The Mac-only address lookup is behind TARGET_OS_OSX; where the host's own address cannot be known (iOS) a controller in pairing mode is used without bonding. Settings row DM_SW2, off by default: with it off no Bluetooth client is created, so no permission prompt appears. With it on, a controller held in Sync advertises no host and the game bonds it with the console's 0x15 commands (this Mac's address and two fresh random keys; the console's constants are not needed), and it keeps playing on the same link; from then on a button press wakes it toward this Mac and it connects without Sync. A controller advertising another host (a Switch 2 nearby) is never written to. A Pro Controller 2, or a left and a right Joy-Con 2 together, is one Pro-style pad with motion as the player's six-axis sensor; one Joy-Con alone is a sideways pad. Home, A and B take part in the hold-to-quit prompt. Checked on an M1 Pro, macOS 27.2, with a left and a right Joy-Con 2: Metroid Dread 2.1.0 (both woke and played as one pair, a Joy-Con held in Sync during the game bonded and kept playing, Home hold and A quit; a Joy-Con paired back to a Switch 2 beside the Mac woke for it and was left alone until Sync paired it with the Mac again; macOS asked for Bluetooth on the first start of a freshly packed app and not on the second) and Super Mario Odyssey 1.3.0 (motion: the cap throw by shaking). The Pro Controller 2 is untested. Protocol facts are from the community's notes (switch2mac, ndeadly/switch2_controller_research, trevlars/switch2-controllers-linux, Nadeflore/switch2-controllers); the code was written from them and copies none. Motion: the gyro scale is measured (0.0607 degrees per second per count: 14 tilts edge to wall, 90 degrees by the accelerometer, read 1.153 times as much at the nominal 0.070, on a left and a right Joy-Con 2); each sample is timed by the controller's millisecond clock (the report's first four bytes) instead of its arrival, so a burst of notifications or a lost report no longer bends the integration (s2_clock_sample); and the gyro offset is there from the first sample: the one learned for that controller before (kept under its serial number), or a right Joy-Con 2's factory offset at 0x13040, which matches its rest offset. Front-ends: new: DM_SW2=1 (settings row, off by default) turns on Switch 2 controllers over Bluetooth LE; the Mac app's Info.plist needs NSBluetoothAlwaysUsageDescription (pack_app.py writes it), without which the host stays off Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dles, coded as the console codes it: logarithmic frequency codes, the sample count, each of the game's values in its own 5 ms sample (2 of 3, issue seedds#1267) The game's vibration of a player's two full-key motors reaches a Switch 2 pad through haptics_apple.m: dm_haptics_apple_set_sink gives the player an output of its own instead of a Core Haptics engine, on the rumble queue, with DM_RUMBLE_GAIN and DM_RUMBLE_MIN applied as the engines get them, and silence on a suspension or a route change. switch2_proto.h s2_rumble_pick says which motor a controller plays: each Joy-Con of a pair its side, a Joy-Con alone the stronger of the two in each band, a Pro Controller 2 one per grip. No npad change: the existing full-key and handheld vibration handles drive it. The report to a controller's vibration channel (the right Joy-Con 2's FA19B0FB-CD1F-46A7-84A1-BBB09E00C149, the left one's 289326CB-A471-485D-A8F4-240C14F18241) is a zero byte and a 16-byte block per actuator: 0x40 | the number of samples << 4 | a sequence, then up to three five-byte samples, played in turn. A sample is two bands, low then high, each a 10-bit frequency code and a 10-bit amplitude. The frequency code is logarithmic, 96 steps an octave with 333 at 110 Hz (9.935 Hz to 16034 Hz); the amplitude is linear, 1023 at full; both bands together are limited to 0.98 (s2_rumble_cap). Hertz and amplitude are rounded as the console rounds them: truncated, then of that code and the next the one that decodes nearer. Checked against the Switch 2's own encoder on 200,000 random values (one to three samples, 5 Hz to 3 kHz, amplitudes past full scale too): no byte differed. The game sets its vibration about every 5 ms and holds each value until the next, so a value set for one step is a 5 ms pulse (a bounce, a click). Each value plays once, in the first 5 ms sample that ends after it was set (switch2_proto.h, Rumble timing: s2_rumble_log, s2_rumble_slot), three samples to a packet every 15 ms; a sample with no new value repeats the one before, and values that pile up wait at most five samples. That is how the console plays them: one sample per value, in order. Holding a value until the next packet instead stretched each one-step pulse to two or three samples: replayed against a recording of the game's values in Nintendo Switch 2 Welcome Tour's bead and rubber-ball exhibits (892 non-zero values over 8 minutes), the energy per Joy-Con came to 1.8 and 2.2 times the console's, and the pulses averaged 2 samples instead of 1. With the slots it is 1.00, with the same 667 and 1,142 pulses, each one sample long. A buzz ends with three packets of silence, since one write without response can be lost. DM_SW2_VERBOSE logs the tick's spacing and the packets each second: on an M1 Pro, 67 ticks a second, the longest gap 16 ms, no write refused for a full buffer. The console also corrects each band's amplitude by its frequency, with tables of its own per controller model; that is not done here. Checked on an M1 Pro, macOS 27.2, with a left and a right Joy-Con 2 in Super Mario Odyssey 1.3.0 as one pair (cap throw, ground pound, captures, hits) and in Nintendo Switch 2 Welcome Tour's vibration exhibits. t_switch2: the codes and their rounding, the 0.98 limit, the block layout with its count, which motor each controller plays, and the slots (a one-step pulse is one sample, a value for the other motor takes no slot, two values in a slot, a pile-up, a late tick). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sor per Joy-Con, splits when the game asks, and the Switch 2 Joy-Cons choose by a three-second hold (3 of 3, issue seedds#1267) A front end that reads Joy-Cons one by one reports them to the npad layer (dm_input.h: dm_joy_attach, dm_joy_set, dm_motion_set_joy, dm_motion_clear_joy; no controller-specific names, so Switch 1 Joy-Cons and seedds#585 / seedds#878 can feed it later). Nothing changes until one does. hle_hid.c then shows the game what it asks for, from the styles it supports (SetSupportedNpadStyleSet, recorded before and never consulted): docked, a pad holding both Joy-Cons is one JoyDual npad (both Joy-Cons' buttons, rail buttons included, which fill no longer masks away for these styles; each stick on its side; a six-axis handle per Joy-Con); on single assignment (SetNpadJoyAssignmentModeSingle and its forms, SetNpadJoyAssignmentModeDual, GetNpadJoyAssignment) the left Joy-Con stays on the npad, or the one the game named, and the other takes the lowest free supported npad; one Joy-Con alone is JoyLeft or JoyRight. The controller applet splits a pair when the game wants more players than there are controllers. A game that supports no Joy-Con style reads the pad as a full-key controller, as before. Vibration handles exist for the Joy-Con styles (types 5, 6 and 7) and reach the motor of their Joy-Con on whichever npad it is; a full-key handle the game got before the Joy-Cons connected still reaches them (Super Mario Odyssey keeps sending to its full-key handles after asking for the JoyDual ones). Handheld mode: player 1's Joy-Cons count as attached to the console (the Handheld npad) and are never split. The Switch 2 transport (pad_switch2_apple.m) reports each Joy-Con's own buttons, stick and sensor (not while the game has no input: the front end's new blocked callback), keeps a left and a right one that connect together as a pair, and lets the player choose on the controllers, as a Switch's Change Grip/Order screen does, without its screen: SL + SR held three seconds on a Joy-Con of a pair gives it a player of its own; L on a left one alone and R on a right one alone, held together three seconds, pairs them (switch2_proto.h s2_gesture, s2_hold_update). The player lights show the result. DM_PAD_MERGE keeps every pad full-key. Checked on an M1 Pro, macOS 27.2, with a left and a right Joy-Con 2: Super Mario Odyssey 1.3.0 (a JoyDual npad: the two-handed up and spin throws; two-player mode splits the pair through the applet; rumble on both; the split and join holds), Super Mario Bros. Wonder 1.2.1 (choosing two players splits the pair), Super Smash Bros. Ultimate 13.0.5 (the SL + SR hold makes two sideways players; a 1v1 with a Joy-Con each, rail buttons as shoulders, rumble on each). t_hid: 175 checks (t_joycons: inert until a Joy-Con is reported, JoyDual with rail buttons, the unsupported-style fallback, single assignment and the other half's npad, the applet split, vibration handles per style, handheld); t_switch2: 80 checks (the Joy-Con buttons, the gestures and their timing). Not checked: more than two Joy-Cons, the Pro Controller 2. Front-ends: new: dm_joy_attach / dm_joy_set / dm_motion_set_joy / dm_motion_clear_joy (dm_input.h) let a front end report Joy-Cons one by one; until it does, nothing changes Front-ends: interface: dm_switch2_front has a blocked callback (NULL: never blocked) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y-Con's sensor (dm_joy_mouse), the game reads it as JcmsStates and as an Nmouse pointer, and a Joy-Con 2 pad shows the Joy-Con 2 npad styles (issue seedds#1267, after seedds#1363) A Switch 2 game's mouse mode did nothing with Joy-Con 2s: the host answered as having no sensor (GetJcmsStates none, GetNmouseHandles none), and a Joy-Con 2 pad had only the plain Joy-Con styles, while a Switch 2 game can support only their Joy-Con 2 forms. Nintendo Switch 2 Welcome Tour's mouse exhibits support only style 0x1000 and test a pair with 0x1004, a left Joy-Con with 0x2008 and a right one with 0x4000 beside JoyRight: so bits 12, 13 and 14 are taken as the Joy-Con 2 forms of JoyDual, JoyLeft and JoyRight (inferred, not documented). The npad layer (hle_hid.c, dm_input.h), neutral as the rest of the Joy-Con API: - dm_joy_mouse(pad, side, dx, dy, state): a Joy-Con's movement since its last report and whether it is connected and on a surface. Nothing changes for a Joy-Con that never calls it. - dm_joy_attach takes DM_JOY_2: the pad's npad then shows the Joy-Con 2 style beside the plain one, to a game that supports it. - GetJcmsStates / GetJcmsState read a ring of 16 states per player and Joy-Con. A JcmsState as Welcome Tour reads it (main+0x253540): 8 bytes it does not read, the sampling number at 8 (newest first), the movement at 0x10 and 0x14, attributes at 0x18 (bit 0 connected, bit 1 on a surface). JcmsType 0 is the left Joy-Con, 1 the right. - Nmouse: a handle per Joy-Con whose sensor reports, the one last used on a surface first and kept first while lifted (Welcome Tour moves its pointer by the first handle only). An NmouseState (main+0x253b2c) is 48 bytes: 8 bytes, the Switch's MouseState fields (sampling number, position on the game's pointer range, movement, wheel), buttons at 0x28 (left 1 is R / ZR on a right Joy-Con, L / ZL on a left one; right 2), attributes at 0x2c (bit 1 connected, which the game requires). SetNmousePointerPosition moves it; the movement is a quarter of the sensor's counts. GetMousePointerSpeedScale answers the default, 1. - DM_JCMS_LOG=1 logs the game's sensor and pointer calls, at most once a second each kind. The Switch 2 transport turns the sensor on with its own feature bit, 0x10 (S2_FEATURE_MOUSE; not for the Pro Controller 2, which has none). Measured on a right Joy-Con 2 slid on a desk: report bytes 0x10 and 0x12 are 16-bit position counters that wrap (x right, y toward the player); 0x14 and 0x16 jump from about 1,600 and 150 on a surface to about 4,600 and 3,200 when lifted, and 0x16 under 1,000 is taken as on a surface. While lifted no movement is reported, since the counters drift with nothing under them. Checked on an M1 Pro, macOS 27.2, with a left and a right Joy-Con 2 in Nintendo Switch 2 Welcome Tour (040057C02159A000, v262144; its profile and host fixes are their own pull request): the cursor follows either Joy-Con on the desk, the one last used takes it, R clicks, and the mouse exhibits play. t_hid: the states and their order, none before a Joy-Con reports, the pointer handles and their order (also while lifted), the pointer state, the Joy-Con 2 style beside JoyDual and none for a plain pair. t_switch2: the counters, their wrap and the surface. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JakePre
force-pushed
the
switch2-pr4-mouse
branch
from
November 8, 2026 19:01
d8011bc to
0067d5f
Compare
seedds
added a commit
that referenced
this pull request
Nov 9, 2026
…y-Con's sensor (dm_joy_mouse), the game reads it as JcmsStates and as an Nmouse pointer, and a Joy-Con 2 pad shows the Joy-Con 2 npad styles (issue #1267, after #1363) A Switch 2 game's mouse mode did nothing with Joy-Con 2s: the host answered as having no sensor (GetJcmsStates none, GetNmouseHandles none), and a Joy-Con 2 pad had only the plain Joy-Con styles, while a Switch 2 game can support only their Joy-Con 2 forms. Nintendo Switch 2 Welcome Tour's mouse exhibits support only style 0x1000 and test a pair with 0x1004, a left Joy-Con with 0x2008 and a right one with 0x4000 beside JoyRight: so bits 12, 13 and 14 are taken as the Joy-Con 2 forms of JoyDual, JoyLeft and JoyRight (inferred, not documented). The npad layer (hle_hid.c, dm_input.h), neutral as the rest of the Joy-Con API: - dm_joy_mouse(pad, side, dx, dy, state): a Joy-Con's movement since its last report and whether it is connected and on a surface. Nothing changes for a Joy-Con that never calls it. - dm_joy_attach takes DM_JOY_2: the pad's npad then shows the Joy-Con 2 style beside the plain one, to a game that supports it. - GetJcmsStates / GetJcmsState read a ring of 16 states per player and Joy-Con. A JcmsState as Welcome Tour reads it (main+0x253540): 8 bytes it does not read, the sampling number at 8 (newest first), the movement at 0x10 and 0x14, attributes at 0x18 (bit 0 connected, bit 1 on a surface). JcmsType 0 is the left Joy-Con, 1 the right. - Nmouse: a handle per Joy-Con whose sensor reports, the one last used on a surface first and kept first while lifted (Welcome Tour moves its pointer by the first handle only). An NmouseState (main+0x253b2c) is 48 bytes: 8 bytes, the Switch's MouseState fields (sampling number, position on the game's pointer range, movement, wheel), buttons at 0x28 (left 1 is R / ZR on a right Joy-Con, L / ZL on a left one; right 2), attributes at 0x2c (bit 1 connected, which the game requires). SetNmousePointerPosition moves it; the movement is a quarter of the sensor's counts. GetMousePointerSpeedScale answers the default, 1. - DM_JCMS_LOG=1 logs the game's sensor and pointer calls, at most once a second each kind. The Switch 2 transport turns the sensor on with its own feature bit, 0x10 (S2_FEATURE_MOUSE; not for the Pro Controller 2, which has none), only once the game has set up the sensors or the pointer (InitializeJcms / InitializeNmouse: dm_joy_mouse_wanted), as the console turns it on only for a game that uses it; a controller that connected before gets the two feature commands again with the bit, and keeps it while connected. Measured on a right Joy-Con 2 slid on a desk: report bytes 0x10 and 0x12 are 16-bit position counters that wrap (x right, y toward the player); 0x14 and 0x16 jump from about 1,600 and 150 on a surface to about 4,600 and 3,200 when lifted, and 0x16 under 1,000 is taken as on a surface. While lifted no movement is reported, since the counters drift with nothing under them. Checked on an M1 Pro, macOS 27.2, with a left and a right Joy-Con 2 in Nintendo Switch 2 Welcome Tour (040057C02159A000, v262144; its profile and host fixes are their own pull request): the cursor follows either Joy-Con on the desk, the one last used takes it, R clicks, and the mouse exhibits play. t_hid: the states and their order, none before a Joy-Con reports, the pointer handles and their order (also while lifted), the pointer state, the Joy-Con 2 style beside JoyDual and none for a plain pair. t_switch2: the counters, their wrap and the surface. Front-ends: new: dm_joy_mouse (dm_input.h) reports a Joy-Con's mouse sensor, dm_joy_mouse_wanted says whether the game has set the sensors up (turn a sensor on only then), and dm_joy_attach takes DM_JOY_2 for Joy-Con 2s; until a front end calls them, nothing changes PR #1426 Co-authored-by: JakePre <130175182+JakePre@users.noreply.github.com>
Owner
Know-It-All-Brother
pushed a commit
to Know-It-All-Brother/nxnative
that referenced
this pull request
Nov 9, 2026
…y-Con's sensor (dm_joy_mouse), the game reads it as JcmsStates and as an Nmouse pointer, and a Joy-Con 2 pad shows the Joy-Con 2 npad styles (issue seedds#1267, after seedds#1363) A Switch 2 game's mouse mode did nothing with Joy-Con 2s: the host answered as having no sensor (GetJcmsStates none, GetNmouseHandles none), and a Joy-Con 2 pad had only the plain Joy-Con styles, while a Switch 2 game can support only their Joy-Con 2 forms. Nintendo Switch 2 Welcome Tour's mouse exhibits support only style 0x1000 and test a pair with 0x1004, a left Joy-Con with 0x2008 and a right one with 0x4000 beside JoyRight: so bits 12, 13 and 14 are taken as the Joy-Con 2 forms of JoyDual, JoyLeft and JoyRight (inferred, not documented). The npad layer (hle_hid.c, dm_input.h), neutral as the rest of the Joy-Con API: - dm_joy_mouse(pad, side, dx, dy, state): a Joy-Con's movement since its last report and whether it is connected and on a surface. Nothing changes for a Joy-Con that never calls it. - dm_joy_attach takes DM_JOY_2: the pad's npad then shows the Joy-Con 2 style beside the plain one, to a game that supports it. - GetJcmsStates / GetJcmsState read a ring of 16 states per player and Joy-Con. A JcmsState as Welcome Tour reads it (main+0x253540): 8 bytes it does not read, the sampling number at 8 (newest first), the movement at 0x10 and 0x14, attributes at 0x18 (bit 0 connected, bit 1 on a surface). JcmsType 0 is the left Joy-Con, 1 the right. - Nmouse: a handle per Joy-Con whose sensor reports, the one last used on a surface first and kept first while lifted (Welcome Tour moves its pointer by the first handle only). An NmouseState (main+0x253b2c) is 48 bytes: 8 bytes, the Switch's MouseState fields (sampling number, position on the game's pointer range, movement, wheel), buttons at 0x28 (left 1 is R / ZR on a right Joy-Con, L / ZL on a left one; right 2), attributes at 0x2c (bit 1 connected, which the game requires). SetNmousePointerPosition moves it; the movement is a quarter of the sensor's counts. GetMousePointerSpeedScale answers the default, 1. - DM_JCMS_LOG=1 logs the game's sensor and pointer calls, at most once a second each kind. The Switch 2 transport turns the sensor on with its own feature bit, 0x10 (S2_FEATURE_MOUSE; not for the Pro Controller 2, which has none), only once the game has set up the sensors or the pointer (InitializeJcms / InitializeNmouse: dm_joy_mouse_wanted), as the console turns it on only for a game that uses it; a controller that connected before gets the two feature commands again with the bit, and keeps it while connected. Measured on a right Joy-Con 2 slid on a desk: report bytes 0x10 and 0x12 are 16-bit position counters that wrap (x right, y toward the player); 0x14 and 0x16 jump from about 1,600 and 150 on a surface to about 4,600 and 3,200 when lifted, and 0x16 under 1,000 is taken as on a surface. While lifted no movement is reported, since the counters drift with nothing under them. Checked on an M1 Pro, macOS 27.2, with a left and a right Joy-Con 2 in Nintendo Switch 2 Welcome Tour (040057C02159A000, v262144; its profile and host fixes are their own pull request): the cursor follows either Joy-Con on the desk, the one last used takes it, R clicks, and the mouse exhibits play. t_hid: the states and their order, none before a Joy-Con reports, the pointer handles and their order (also while lifted), the pointer state, the Joy-Con 2 style beside JoyDual and none for a plain pair. t_switch2: the counters, their wrap and the surface. Front-ends: new: dm_joy_mouse (dm_input.h) reports a Joy-Con's mouse sensor, dm_joy_mouse_wanted says whether the game has set the sensors up (turn a sensor on only then), and dm_joy_attach takes DM_JOY_2 for Joy-Con 2s; until a front end calls them, nothing changes PR seedds#1426 Co-authored-by: JakePre <130175182+JakePre@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #1363 (and so on #1349 and #1346). The first three commits are theirs; only the last, "The Joy-Con 2's mouse sensor and pointer…", is new. I'll rebase once they land.
What and why
This follows the three PRs agreed in #1267. It's small (about 200 lines) and stays within that device: it adds the Joy-Con 2's mouse sensor, which those PRs left out. A Switch 2 game's mouse mode did nothing with Joy-Con 2s. The host answered as having no sensor (
GetJcmsStatesnone,GetNmouseHandlesnone). A Joy-Con 2 pad also had only the plain Joy-Con styles, while a Switch 2 game can support only their Joy-Con 2 forms.The npad layer (
hle_hid.c,dm_input.h), neutral like the rest of the Joy-Con API in #1363:dm_joy_mouse(pad, side, dx, dy, state): a Joy-Con's movement since its last report, and whether it is connected and on a surface. Nothing changes for a Joy-Con that never calls it.dm_joy_attachtakesDM_JOY_2: the pad's npad then shows the Joy-Con 2 style beside the plain one, to a game that supports it.0x1000, and test a pair with0x1004, a left Joy-Con with0x2008and a right one with0x4000beside JoyRight.GetJcmsStates/GetJcmsState: a ring of 16 states per player and Joy-Con.main+0x253540), is 8 bytes it doesn't read, the sampling number at 8 (newest first), the movement at 0x10 and 0x14, and attributes at 0x18 (bit 0 connected, bit 1 on a surface).main+0x253b2c) is 48 bytes: 8 bytes, the Switch's MouseState fields, buttons at 0x28 (left 1 is R or ZR on a right Joy-Con, L or ZL on a left one; right 2), and attributes at 0x2c (bit 1 connected, which the game requires).SetNmousePointerPositionmoves it. The movement is a quarter of the sensor's counts.DM_JCMS_LOG=1: logs the game's sensor and pointer calls, at most once a second each kind.The Switch 2 transport turns the sensor on with its own feature bit,
0x10(S2_FEATURE_MOUSE). It's left off for the Pro Controller 2, which has no sensor. Measured on a right Joy-Con 2 slid on a desk:Overlap with the Welcome Tour PR (#1425): that one adds
GetJcmsStateas a cleared state (no sensor), so the game runs onmain. This one fills it from the sensor. Whichever lands second, I'll rebase.Reference entry: The Joy-Con 2 mouse sensor and pointer.
docs_symptoms.pywas run.Checked
Tests: these all pass:
make -C dm/host/tests GAME=0100000000010000 runt_hid, now 201 checks: the states and their order, none before a Joy-Con reports, the pointer handles and their order (also while lifted), the pointer state, the Joy-Con 2 style beside JoyDual, and none for a plain pairt_switch2, now 117 checks: the counters, their wrap and the surfacemake -C dm/gfx/tests GAME=0100000000010000 runtest_docs.py,env_switches.py --checklint_c.py tidy(LLVM 23.1.5): no new findingsGames run: Nintendo Switch 2 Welcome Tour (040057C02159A000, v262144), with a left and a right Joy-Con 2. The cursor follows either Joy-Con on the desk, the one last used takes it, R clicks, and the mouse exhibits play.
Not checked:
Devices and OS: M1 Pro, macOS 27.2.
regress.py: I didn't run
check.impactnames Hades, Breath of the Wild, Pokémon Scarlet and Tears of the Kingdom, the four profiles with a usage manifest. They reach it through the hid npad calls next to the changed lines.dm_joy_mouseordm_joy_attachwithDM_JOY_2. With no sensor,GetJcmsStatesandGetNmouseHandlesstill give none and the styles are as before;t_hidchecks both.regress.py listfinds none, since my games are archived off it.If you want
checkon any of these, tell me which.Front ends
Front-ends: new: dm_joy_mouse (dm_input.h) reports a Joy-Con's mouse sensor, and dm_joy_attach takes DM_JOY_2 for Joy-Con 2s; until a front end calls them, nothing changes
Docs
docs_symptoms.pyrun🤖 Generated with Claude Code