Skip to content

Commit

Permalink
fix(SourceSteamDeck): configure trackpads when disabling lizard mode
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowApex committed Nov 20, 2024
1 parent 0eb697b commit 8c1e4c2
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 13 deletions.
62 changes: 53 additions & 9 deletions src/drivers/steam_deck/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use super::{
AccelerometerEvent, AccelerometerInput, AxisEvent, AxisInput, BinaryInput, ButtonEvent,
Event, TouchAxisInput, TriggerEvent, TriggerInput,
},
hid_report::{PackedMappingsReport, PackedRumbleReport, ReportType},
hid_report::{PackedMappingsReport, PackedRumbleReport, Register, ReportType, TrackpadMode},
};

/// Vendor ID
Expand Down Expand Up @@ -93,18 +93,62 @@ impl Driver {
/// Set lizard mode, which will automatically try to emulate mouse/keyboard
/// if enabled.
pub fn set_lizard_mode(&self, enabled: bool) -> Result<(), Box<dyn Error + Send + Sync>> {
// Initialize the report to send
let report = match enabled {
true => PackedMappingsReport {
// Lizard mode enabled
if enabled {
// Enable keyboard emulation
let report = PackedMappingsReport {
report_id: ReportType::DefaultMappings as u8,
},
false => PackedMappingsReport {
};
let buf = report.pack()?;
let _bytes_written = self.device.write(&buf)?;

// Enable mouse emulation on the right pad
let report = PackedMappingsReport {
report_id: ReportType::DefaultMouse as u8,
};
let buf = report.pack()?;
let _bytes_written = self.device.write(&buf)?;

// Enable smoothing
self.write_register(Register::SmoothAbsoluteMouse, 0x01)?;
}
// Lizard mode disabled
else {
// Disable keyboard emulation (for a few seconds)
let report = PackedMappingsReport {
report_id: ReportType::ClearMappings as u8,
},
};
};
let buf = report.pack()?;
let _bytes_written = self.device.write(&buf)?;

// Disable mouse emulation on the right pad
self.write_register(Register::RPadMode, TrackpadMode::None as u16)?;

// Disable smoothing
self.write_register(Register::SmoothAbsoluteMouse, 0x00)?;
}

Ok(())
}

/// Write the given register value to the gamepad device
pub fn write_register(
&self,
register: Register,
value: u16,
) -> Result<(), Box<dyn Error + Send + Sync>> {
// Create a buffer for the report
let mut buf = [0; 64];
buf[0] = ReportType::WriteRegister as u8;
// Only allow writing one register at a time (size: 3 bytes)
buf[1] = 3;
// Register is 8 bits
buf[2] = register as u8;
// Value is 16 bits, with the low bits first
buf[3] = (value & 0xff) as u8;
buf[4] = (value >> 8) as u8;

// Write the report to the device
let buf = report.pack()?;
let _bytes_written = self.device.write(&buf)?;

Ok(())
Expand Down
104 changes: 102 additions & 2 deletions src/drivers/steam_deck/hid_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,111 @@ impl TryFrom<u8> for ReportType {
}
}

/// Register settings
pub enum Register {
MouseSensitivity = 0x00,
MouseAcceleration = 0x01,
TrackballRotationAngle = 0x02,
HapticIntensityUnused = 0x03,
LeftGamepadStickEnabled = 0x04,
RightGamepadStickEnabled = 0x05,
UsbDebugMode = 0x06,
LPadMode = 0x07,
RPadMode = 0x08,
RPadMargin = 0x18,
GyroMode = 0x30,
MousePointerEnabled = 0x09,

DPadDeadzone,
MinimumMomentumVel,
MomentumDecayAmmount,
TrackpadRelativeModeTicksPerPixel,
HapticIncrement,
DPadAngleSin,
DPadAngleCos,
MomentumVerticalDivisor,
MomentumMaximumVelocity,
TrackpadZOn,

TrackpadZOff,
SensitivyScaleAmmount,
LeftTrackpadSecondaryMode,
RightTrackpadSecondaryMode,
SmoothAbsoluteMouse,
SteamButtonPowerOffTime,
Unused1,
TrackpadOuterRadius,
TrackpadZOnLeft,
TrackpadZOffLeft,

TrackpadOuterSpinVel,
TrackpadOuterSpinRadius,
TrackpadOuterSpinHorizontalOnly,
TrackpadRelativeModeDeadzone,
TrackpadRelativeModeMaxVel,
TrackpadRelativeModeInvertY,
TrackpadDoubleTapBeepEnabled,
TrackpadDoubleTapBeepPeriod,
TrackpadDoubleTapBeepCount,
TrackpadOuterRadiusReleaseOnTransition,

RadialModeAngle,
HapticIntensityMouseMode,
LeftDPadRequiresClick,
RightDPadRequiresClick,
LedBaselineBrightness,
LedUserBrightness,
EnableRawJoystick,
EnableFastScan,
ImuMode,
WirelessPacketVersion,

SleepInactivityTimeout,
TrackpadNoiseThreshold,
LeftTrackpadClickPressure,
RightTrackpadClickPressure,
LeftBumperClickPressure,
RightBumperClickPressure,
LeftGripClickPressure,
RightGripClickPressure,
LeftGrip2ClickPressure,
RightGrip2ClickPressure,

PressureMode,
ControllerTestMode,
TriggerMode,
TrackpadZThreshold,
FrameRate,
TrackpadFiltCtrl,
TrackpadClip,
DebugOutputSelect,
TriggerThresholdPercent,
TrackpadFrequencyHopping,

HapticsEnabled,
SteamWatchdogEnable,
TimpTouchThresholdOn,
TimpTouchThresholdOff,
FreqHopping,
TestControl,
HapticMasterGainDb,
ThumbTouchThresh,
DevicePowerStatus,
HapticIntensity,

StabilizerEnabled,
TimpModeMte,
}

/// Trackpad modes
pub enum TrackpadMode {
AbsoluteMouse = 0x00,
RelativeMouse = 0x01,
DPadFourWayDiscrete = 0x02,
DPadFourWayOverlap = 0x03,
DPadEightWay = 0x04,
RadialMode = 0x05,
AbsoluteDPad = 0x06,
None = 0x07,
GestureKeyboard = 0x08,
}

#[derive(PackedStruct, Debug, Copy, Clone, PartialEq)]
Expand Down
10 changes: 8 additions & 2 deletions src/input/source/hidraw/steam_deck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,12 +334,15 @@ fn normalize_axis_value(event: steam_deck::event::AxisEvent) -> InputValue {
let min = steam_deck::hid_report::PAD_X_MIN;
let max = steam_deck::hid_report::PAD_X_MAX;
let x = normalize_signed_value(value.x as f64, min, max);
let x = (x + 1.0) / 2.0; // Convert from -1.0 - 1.0 range to 0.0 - 1.0 range
let x = Some(x);

let min = steam_deck::hid_report::PAD_Y_MAX; // uses inverted Y-axis
let max = steam_deck::hid_report::PAD_Y_MIN;
let y = normalize_signed_value(value.y as f64, min, max);
let y = Some(-y); // Y-Axis is inverted
let y = -y; // Y-axis is inverted
let y = (y + 1.0) / 2.0; // Convert from -1.0 - 1.0 range to 0.0 - 1.0 range
let y = Some(y);

InputValue::Touch {
index: value.index,
Expand All @@ -353,12 +356,15 @@ fn normalize_axis_value(event: steam_deck::event::AxisEvent) -> InputValue {
let min = steam_deck::hid_report::PAD_X_MIN;
let max = steam_deck::hid_report::PAD_X_MAX;
let x = normalize_signed_value(value.x as f64, min, max);
let x = (x + 1.0) / 2.0; // Convert from -1.0 - 1.0 range to 0.0 - 1.0 range
let x = Some(x);

let min = steam_deck::hid_report::PAD_Y_MAX; // uses inverted Y-axis
let max = steam_deck::hid_report::PAD_Y_MIN;
let y = normalize_signed_value(value.y as f64, min, max);
let y = Some(-y); // Y-Axis is inverted
let y = -y; // Y-axis is inverted
let y = (y + 1.0) / 2.0; // Convert from -1.0 - 1.0 range to 0.0 - 1.0 range
let y = Some(y);

InputValue::Touch {
index: value.index,
Expand Down

0 comments on commit 8c1e4c2

Please sign in to comment.