x360/
x360.rs

1use std::thread;
2use std::time::Duration;
3use vigem_rust::{Client, X360Button, X360Report};
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 x360 = client.new_x360_target().plugin()?;
13    println!("Plugged in virtual Xbox 360 controller");
14
15    // Wait for the controller to be ready
16    // The virtual controller needs a moment to be recognized
17    // by the system before it can receive updates.
18    x360.wait_for_ready()?;
19    println!("Controller is ready. You can test it at https://hardwaretester.com/gamepad");
20
21    // Set up a notification listener in a separate thread
22    // This allows us to react to feedback from the system, like rumble or LED changes.
23    let notifications = x360.register_notification()?;
24    thread::spawn(move || {
25        println!("Notification Thread Started. Waiting for feedback...");
26        while let Ok(Ok(notification)) = notifications.recv() {
27            println!("Notification Thread Received feedback:");
28            println!(
29                "  - Rumble: Large Motor = {}, Small Motor = {}",
30                notification.large_motor, notification.small_motor
31            );
32            println!("  - LED Number/Player Index: {}", notification.led_number);
33        }
34    });
35
36    // Here, we'll send reports to the controller to simulate input.
37    let mut report = X360Report::default();
38    let mut angle: f64 = 0.0;
39    let mut step = 0;
40
41    loop {
42        // Animate the left thumbstick in a circle
43        angle += 0.1;
44        let (sin, cos) = angle.sin_cos();
45        report.thumb_lx = (sin * 32767.0) as i16;
46        report.thumb_ly = (cos * 32767.0) as i16;
47
48        // Alternate pressing A and B buttons
49        if step % 2 == 0 {
50            report.buttons = X360Button::A;
51        } else {
52            report.buttons = X360Button::B;
53        }
54
55        // Send the updated report to the controller
56        x360.update(&report)?;
57
58        thread::sleep(Duration::from_millis(16));
59        step += 1;
60    }
61}