#[repr(C, packed(1))]pub struct Ds4Touch {
pub packet_counter: u8,
pub is_up_tracking_num_1: u8,
pub touch_data_1: [u8; 3],
pub is_up_tracking_num_2: u8,
pub touch_data_2: [u8; 3],
}Expand description
Represents a single packet of touchpad data for a DualShock 4 controller.
The DS4 can track up to two simultaneous touch points. This struct contains
the state for both potential touches, along with a counter to sequence the packets.
It is used within the Ds4ReportExData struct.
Fields§
§packet_counter: u8A timestamp or packet counter that increments with each new touch data packet, used to sequence events.
is_up_tracking_num_1: u8Touch state and tracking ID for the first touch point. This is a bit-packed field:
- The most significant bit (MSB,
0x80) indicates the contact state. This is “active-low”, meaning0for touch down and1for touch up. - The lower 7 bits (
0x7F) are the tracking ID for the finger. This ID is unique for a single press-drag-release gesture and increments for a new press.
touch_data_1: [u8; 3]The raw X/Y coordinate data for the first touch point, with a resolution of 1920x943.
This is a packed 24-bit value encoding a 12-bit X and 12-bit Y coordinate. The middle byte holds the 4 least significant bits of X and the 4 most significant bits of Y.
You can unpack the coordinates like this:
let x = (self.touch_data_1[0] as u16) | (((self.touch_data_1[1] & 0x0F) as u16) << 8);
let y = (((self.touch_data_1[1] & 0xF0) as u16) >> 4) | ((self.touch_data_1[2] as u16) << 4);is_up_tracking_num_2: u8Touch state and tracking ID for the second touch point.
Formatted identically to is_up_tracking_num_1.
touch_data_2: [u8; 3]The raw X/Y coordinate data for the second touch point.
Formatted identically to touch_data_1.
Implementations§
Source§impl Ds4Touch
impl Ds4Touch
Sourcepub fn set_touch_1(&mut self, is_down: bool, tracking_num: u8, x: u16, y: u16)
pub fn set_touch_1(&mut self, is_down: bool, tracking_num: u8, x: u16, y: u16)
Sets the state for the first touch contact, abstracting away the bit-packing.
§Arguments
is_down-trueif the finger is touching the pad,falseotherwise.tracking_num- A unique ID for the finger gesture (0-127).x- The X coordinate (0-1919).y- The Y coordinate (0-942).
Examples found in repository?
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 // Connect to the ViGEm bus
8 // This can fail if the ViGEm bus driver is not installed.
9 let client = Client::connect()?;
10 println!("Connected to ViGEm bus");
11
12 // Create and plugin the virtual controller
13 let ds4 = client.new_ds4_target().plugin()?;
14 println!("Plugged in virtual DualShock 4 controller");
15
16 // Wait for the controller to be ready
17 ds4.wait_for_ready()?;
18 println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
19
20 let notifications = ds4.register_notification()?;
21 thread::spawn(move || {
22 println!("Notification Thread Started. Waiting for feedback from the host...");
23 while let Ok(Ok(notification)) = notifications.recv() {
24 println!("Notification Thread Received feedback:");
25 println!(
26 " - Rumble: Large Motor = {}, Small Motor = {}",
27 notification.large_motor, notification.small_motor
28 );
29 println!(
30 " - Lightbar Color: R={}, G={}, B={}",
31 notification.lightbar.red, notification.lightbar.green, notification.lightbar.blue
32 );
33 }
34 });
35
36 // Main input loop for extended reports
37 let mut report_ex = Ds4ReportEx::default();
38
39 // Variables to animate the touch point
40 let mut packet_counter: u8 = 0;
41 let mut touch_x: i32 = 0;
42 let mut direction: i32 = 12;
43
44 loop {
45 // Move the touch point back and forth horizontally.
46 if touch_x <= 0 {
47 direction = 12;
48 }
49 if touch_x >= 1919 {
50 direction = -12;
51 }
52 touch_x += direction;
53
54 report_ex.touch_packets_n = 1;
55
56 // Get a mut reference to the touch data struct inside the report.
57 let touch = &mut report_ex.current_touch;
58
59 // This counter should increment for each new packet of touch data (not sure if necessary for functionality).
60 touch.packet_counter = packet_counter;
61 packet_counter = packet_counter.wrapping_add(1);
62
63 touch.set_touch_1(true, 1, touch_x as u16, 471); // Finger 1 is down, centered vertically.
64 touch.set_touch_2(false, 0, 0, 0); // Finger 2 is up (inactive).
65
66 // Send the updated report to the controller
67 ds4.update_ex(&report_ex)?;
68
69 thread::sleep(Duration::from_millis(16));
70 }
71}Sourcepub fn set_touch_2(&mut self, is_down: bool, tracking_num: u8, x: u16, y: u16)
pub fn set_touch_2(&mut self, is_down: bool, tracking_num: u8, x: u16, y: u16)
Sets the state for the second touch contact, abstracting away the bit-packing.
§Arguments
is_down-trueif the finger is touching the pad,falseotherwise.tracking_num- A unique ID for the finger gesture (0-127).x- The X coordinate (0-1919).y- The Y coordinate (0-942).
Examples found in repository?
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 // Connect to the ViGEm bus
8 // This can fail if the ViGEm bus driver is not installed.
9 let client = Client::connect()?;
10 println!("Connected to ViGEm bus");
11
12 // Create and plugin the virtual controller
13 let ds4 = client.new_ds4_target().plugin()?;
14 println!("Plugged in virtual DualShock 4 controller");
15
16 // Wait for the controller to be ready
17 ds4.wait_for_ready()?;
18 println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
19
20 let notifications = ds4.register_notification()?;
21 thread::spawn(move || {
22 println!("Notification Thread Started. Waiting for feedback from the host...");
23 while let Ok(Ok(notification)) = notifications.recv() {
24 println!("Notification Thread Received feedback:");
25 println!(
26 " - Rumble: Large Motor = {}, Small Motor = {}",
27 notification.large_motor, notification.small_motor
28 );
29 println!(
30 " - Lightbar Color: R={}, G={}, B={}",
31 notification.lightbar.red, notification.lightbar.green, notification.lightbar.blue
32 );
33 }
34 });
35
36 // Main input loop for extended reports
37 let mut report_ex = Ds4ReportEx::default();
38
39 // Variables to animate the touch point
40 let mut packet_counter: u8 = 0;
41 let mut touch_x: i32 = 0;
42 let mut direction: i32 = 12;
43
44 loop {
45 // Move the touch point back and forth horizontally.
46 if touch_x <= 0 {
47 direction = 12;
48 }
49 if touch_x >= 1919 {
50 direction = -12;
51 }
52 touch_x += direction;
53
54 report_ex.touch_packets_n = 1;
55
56 // Get a mut reference to the touch data struct inside the report.
57 let touch = &mut report_ex.current_touch;
58
59 // This counter should increment for each new packet of touch data (not sure if necessary for functionality).
60 touch.packet_counter = packet_counter;
61 packet_counter = packet_counter.wrapping_add(1);
62
63 touch.set_touch_1(true, 1, touch_x as u16, 471); // Finger 1 is down, centered vertically.
64 touch.set_touch_2(false, 0, 0, 0); // Finger 2 is up (inactive).
65
66 // Send the updated report to the controller
67 ds4.update_ex(&report_ex)?;
68
69 thread::sleep(Duration::from_millis(16));
70 }
71}Sourcepub fn get_packet_counter(&self) -> u8
pub fn get_packet_counter(&self) -> u8
Returns the packet counter/timestamp for this touch event.
Sourcepub fn get_is_down_1(&self) -> bool
pub fn get_is_down_1(&self) -> bool
Returns true if the first touch point is active (finger is down).
Sourcepub fn get_tracking_num_1(&self) -> u8
pub fn get_tracking_num_1(&self) -> u8
Returns the tracking ID for the first touch point (0-127).
Sourcepub fn get_coords_1(&self) -> (u16, u16)
pub fn get_coords_1(&self) -> (u16, u16)
Returns the (X, Y) coordinates for the first touch point. X is in the range 0-1919, Y is in the range 0-942.
Sourcepub fn get_is_down_2(&self) -> bool
pub fn get_is_down_2(&self) -> bool
Returns true if the second touch point is active (finger is down).
Sourcepub fn get_tracking_num_2(&self) -> u8
pub fn get_tracking_num_2(&self) -> u8
Returns the tracking ID for the second touch point (0-127).
Sourcepub fn get_coords_2(&self) -> (u16, u16)
pub fn get_coords_2(&self) -> (u16, u16)
Returns the (X, Y) coordinates for the second touch point. X is in the range 0-1919, Y is in the range 0-942.