pub struct TargetBuilder<'a, T> { /* private fields */ }Expand description
A builder for creating and plugging in a new virtual target.
Obtain a TargetBuilder from Client::new_x360_target() or Client::new_ds4_target().
Implementations§
Source§impl<'a, T> TargetBuilder<'a, T>
impl<'a, T> TargetBuilder<'a, T>
Source§impl<'a> TargetBuilder<'a, Xbox360>
impl<'a> TargetBuilder<'a, Xbox360>
Sourcepub fn plugin(self) -> Result<TargetHandle<Xbox360>, ClientError>
pub fn plugin(self) -> Result<TargetHandle<Xbox360>, ClientError>
Plugs the configured target into the ViGEm bus.
WARNING: The virtual controller may not be immediately ready for input updates
(e.g., update() calls) upon the return of this function. Windows and the ViGEm
driver require time to fully enumerate the device.
For reliable operation, especially when sending updates immediately after plugging
in, it is highly recommended to call TargetHandle<T>::wait_for_ready and wait for
it to return successfully before sending the first report.
On success, this consumes the builder and returns a TargetHandle which can
be used to control the virtual device.
Examples found in repository?
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}Source§impl<'a> TargetBuilder<'a, DualShock4>
impl<'a> TargetBuilder<'a, DualShock4>
Sourcepub fn plugin(self) -> Result<TargetHandle<DualShock4>, ClientError>
pub fn plugin(self) -> Result<TargetHandle<DualShock4>, ClientError>
Plugs the configured target into the ViGEm bus.
WARNING: The virtual controller may not be immediately ready for input updates
(e.g., update() calls) upon the return of this function. Windows and the ViGEm
driver require time to fully enumerate the device.
For reliable operation, especially when sending updates immediately after plugging
in, it is highly recommended to call TargetHandle<T>::wait_for_ready and wait for
it to return successfully before sending the first report.
On success, this consumes the builder and returns a TargetHandle which can
be used to control the virtual device.
Examples found in repository?
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}More examples
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}