ds4_ex/
ds4_ex.rs

1use std::thread;
2use std::time::Duration;
3use vigem_rust::Client;
4use vigem_rust::controller::ds4::Ds4ReportEx;
5
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}