ds4/
ds4.rs

1use std::thread;
2use std::time::Duration;
3use vigem_rust::{Client, Ds4Button, Ds4Dpad, Ds4Report};
4
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    // Connect to the ViGEm bus
7    // This can fail if the ViGEm bus driver is not installed.
8    let client = Client::connect()?;
9    println!("Connected to ViGEm bus");
10
11    // Create and plugin the virtual controller
12    let ds4 = client.new_ds4_target().plugin()?;
13    println!("Plugged in virtual DualShock 4 controller");
14
15    // Wait for the controller to be ready
16    ds4.wait_for_ready()?;
17    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
18
19    // Set up a notification listener in a separate thread
20    // This allows us to react to feedback from the system, like rumble or LED changes.
21    let notifications = ds4.register_notification()?;
22    thread::spawn(move || {
23        println!("Notification Thread Started. Waiting for feedback from the host...");
24        while let Ok(Ok(notification)) = notifications.recv() {
25            println!("Notification Thread Received feedback:");
26            println!(
27                "  - Rumble: Large Motor = {}, Small Motor = {}",
28                notification.large_motor, notification.small_motor
29            );
30            println!(
31                "  - Lightbar Color: R={}, G={}, B={}",
32                notification.lightbar.red, notification.lightbar.green, notification.lightbar.blue
33            );
34        }
35    });
36
37    // Here, we'll send reports to the controller to simulate input.
38
39    let mut report = Ds4Report::default();
40
41    // Hold the right D-pad button
42    report.set_dpad(Ds4Dpad::East);
43    // Hold the Cross button
44    report.buttons |= Ds4Button::CROSS.bits();
45    // Fully press the right trigger
46    report.trigger_r = 255;
47
48    let mut angle: f64 = 0.0;
49
50    loop {
51        // Animate the right thumbstick in a circle
52        let (sin, cos) = angle.sin_cos();
53
54        // DS4 thumbsticks are 0-255, with 128 as the center.
55        report.thumb_rx = (128.0 + sin * 127.0) as u8;
56        report.thumb_ry = (128.0 + cos * 127.0) as u8;
57
58        // Send the updated report to the controller
59        ds4.update(&report)?;
60
61        thread::sleep(Duration::from_millis(16));
62        angle += 0.05;
63    }
64}