Steam Controller (2026) - Switch 2 - Touchpad (Working)

You can probably skip to the end as this will probably only apply to a select group of people. I recently bought a switch 2 and a steam controller. Astroneer was on sale for $7 dollars so, naturally, that became a full on obsession. As a traditional M&K player the one thing I noticed was that the controls felt clunky on the Switch. It is a very mouse heavy game. I had the idea to use HID Remapper and my new steam controller with the track pad as a mouse. I have not found any posts on this matter but went ahead and did it anyways. If I only knew how much a can of worms this would be I probably never would have attempted this. Switch does not allow mouse input from a controller so I needed to convert the touchpad input to joystick commands using expressions. Expression 3 does just this. It still needs some tuning to be perfect but this is the most usable version I have gotten and honestly im happy with just getting it working now. Full disclosure I did use claude to advance the progress it added smoothing, and tuning and generally improved stuff. It took a lot of iterations so Im posting this so no one else has to go through that.

TLDR: I have finally gotten fairly solid track pad functionality with a steam controller on the switch 2. Copy Paste these expressions and map the left stick x, y to reg 1,2 and right stick x,y to reg 3,4

(I am a new HID Forum user so I can not upload JSON files unfortunatly.)

However I will do my best to explain how to get this working for you.
First you need to set up your mapping Make sure you map your left and right sticks to output Reg 1,2 and 3,4

I have only tested this with Astroneer, on switch 2 which uses UE engine. UE engine has an internal deadzone of 25% this may need to be tuned for specific games but I am not sure.

The tunable parameters in Expression 3 are

Value What it does Adjust
0.02
(once, the line after relu)
Overall sensitivity. Scales every drag speed equally. At 0.02, a quick swipe hits full cursor speed. Whole cursor too slow: 0.025, then 0.03.
Overshooting targets, or medium swipes already hit max speed: 0.015.
Useful range 0.01–0.04. Raising it makes you hit the speed cap with slower swipes, since the stick can’t go past full deflection.
0.5 / 0.5
(first 0.5 mul right after sqrt, second right after swap)
Slow-drag boost. The first number weights the boost curve, which lifts slow drags much more than fast ones. The second weights the plain straight-line response. They must add to 1. Slow drags too slow, fast drags feel right: 0.6/0.4, then 0.7/0.3.
Slow drags twitchy, or tiny finger movements move the cursor too much: 0.3/0.7.
0/1 turns the boost off completely.
More boost also amplifies leftover noise near the floor, so if raising it adds wiggle at rest, raise the noise floor too.
4
(once, the line after 10 store)
Noise floor. Finger speed below this counts as “not moving.” It’s measured after smoothing, in raw pad units per millisecond. Cursor wiggles or creeps while your finger rests still: 6, then 8.
Very slow drags ignored, or a slight delay before movement starts: 3, then 2.
Useful range 2–10.
0.04 / 0.96
(0.04 mul for X, -0.04 mul for Y, 0.96 mul twice)
Smoothing. How much each new reading blends into the running speed. Each pair must add to 1. Change both 0.04s together and keep the minus sign on the Y one. At 0.04 the lag is about 25ms. Slow drags still stutter or pulse: 0.03/0.97 (about 33ms lag), then 0.02/0.98 (about 50ms).
Cursor feels floaty, laggy, or keeps drifting briefly after you stop: 0.06/0.94, then 0.08/0.92.
36 / 91
(36 add twice, 91 mul twice)
Dead-zone edge. The stick jumps straight to this point the instant you move, so tiny movements aren’t lost in Astroneer’s dead zone. They must add to 127. 32/95 matches the documented 25% dead zone exactly. First bit of every drag does nothing, or slow drags need a nudge to get going: 40/87, then 42/85.
Cursor lurches the instant a drag starts, or creeps on the lightest touch: 32/95, then 28/99.

Tuning order: sensitivity first, then the slow-drag boost, then the noise floor. Only adjust smoothing or the dead-zone edge if a specific symptom above points to them.

Expression 1(Left stick dead zone fix for steam controller):
0x00010030 input_state_scaled
0x00010031 input_state_scaled
16 deadzone
2 store
1 store

Expression 2(Right stick dead zone fix for steam controller):
0x00010032 input_state_scaled
0x00010035 input_state_scaled
16 deadzone
4 store
3 store

Expression 3(Right stick touchpad via joystick):
/* ===== X AXIS: finger speed ===== /
0xfffb0004 input_state
dup
5 recall
sub
0x00090018 input_state_binary
mul
7 recall
mul
0.04 mul /
SMOOTHING new-reading weight. Pairs with 0.96 below, must add to 1 /
8 recall
0.96 mul /
SMOOTHING memory weight. Higher = smoother but laggier */
add
0x00090018 input_state_binary
mul
8 store
5 store

/* ===== Y AXIS: finger speed ===== /
0xfffb0005 input_state
dup
6 recall
sub
0x00090018 input_state_binary
mul
7 recall
mul
-0.04 mul /
SMOOTHING, Y copy. Keep the minus sign, it sets up-down direction /
9 recall
0.96 mul /
SMOOTHING, Y copy. Keep equal to the X value */
add
0x00090018 input_state_binary
mul
9 store
6 store

/* ===== SPEED TO STICK AMOUNT ===== /
8 recall
abs
9 recall
abs
max
dup
10 store
4 /
NOISE FLOOR. Raise if cursor wiggles at rest, lower if slow drags are ignored /
sub
relu
0.025 mul /
SENSITIVITY. Higher = faster everywhere /
0
1
clamp
dup
sqrt
0.2 mul /
SLOW BOOST weight. Pairs with 0.8 below, must add to 1 /
swap
0.8 mul /
LINEAR weight. Higher = slow drags slower, less boosted */
add
11 store

/* ===== X OUTPUT to right stick ===== /
8 recall
10 recall
div
11 recall
mul
dup
sign
swap
abs
91 mul /
DEAD ZONE range. Pairs with 36 below, must add to 127 /
36 add /
DEAD ZONE edge. Raise if drags need a nudge to start, lower if cursor lurches */
mul
128 add
0x00090018 input_state_binary
swap
3 recall
ifte
3 store

/* ===== Y OUTPUT to right stick ===== /
9 recall
10 recall
div
11 recall
mul
dup
sign
swap
abs
91 mul /
DEAD ZONE range, Y copy. Keep equal to the X value /
36 add /
DEAD ZONE edge, Y copy. Keep equal to the X value */
mul
128 add
0x00090018 input_state_binary
swap
4 recall
ifte
4 store

0x00090018 input_state_binary
7 store

That’s awesome!

Not sure if I’m doing it right but you should be able to upload the JSON file as attachment now.