pub struct TargetHandle<T> { /* private fields */ }Expand description
An opaque handle to a plugged-in virtual controller.
This handle is returned when a new target is successfully plugged into the bus. It is used to identify the target for subsequent operations like updating its state, listening for notifications, or removing it.
This handle uses reference counting (Arc). Cloning it is cheap and creates another
handle to the same virtual controller. The controller is only unplugged from the bus
when the last handle is dropped.
Implementations§
Source§impl<T> TargetHandle<T>
impl<T> TargetHandle<T>
Sourcepub fn is_attached(&self) -> Result<bool, ClientError>
pub fn is_attached(&self) -> Result<bool, ClientError>
Checks if the virtual controller is still attached to the bus.
This can return false if the controller was manually unplugged
or if the client was dropped.
Sourcepub fn unplug(&self) -> Result<(), ClientError>
pub fn unplug(&self) -> Result<(), ClientError>
Explicitly unplugs the virtual controller from the bus.
After calling this, any further operations on this TargetHandle (and any
of its clones) will fail. The controller is also automatically unplugged when
the last TargetHandle is dropped.
Source§impl TargetHandle<Xbox360>
impl TargetHandle<Xbox360>
Sourcepub fn get_user_index(&self) -> Result<u32, ClientError>
pub fn get_user_index(&self) -> Result<u32, ClientError>
Gets the user index of a virtual Xbox 360 controller.
It doesn’t seem like this method is reliable for getting the dynamic player index assigned by a game.
It often returns 0 even after an index has been assigned.
To reliably get the player index, use TargetHandle<X360>::register_notification and
check the led_number field of the received X360Notification.
Sourcepub fn wait_for_ready(&self) -> Result<(), ClientError>
pub fn wait_for_ready(&self) -> Result<(), ClientError>
Blocks until the virtual controller is fully enumerated and ready to receive updates.
It is recommended to call this after plugging in a new controller if you want to immediately send a report to the controller.
§Example
use vigem_rust::{Client, X360Report};
let client = Client::connect().unwrap();
let x360 = client.new_x360_target().plugin().unwrap();
// Wait for the controller to be ready
x360.wait_for_ready().unwrap();
// Now it's safe to send updates
x360.update(&X360Report::default()).unwrap();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}Sourcepub fn register_notification(
&self,
) -> Result<Receiver<Result<X360Notification, BusError>>, ClientError>
pub fn register_notification( &self, ) -> Result<Receiver<Result<X360Notification, BusError>>, ClientError>
Registers to receive notifications for this Xbox 360 target.
This returns a Receiver that will yield X360Notifications from the bus,
which contain information like rumble data and the controller’s player LED index.
§Important
Calling this function spawns a dedicated background thread that lives as long as
the Receiver does.
§Example
let receiver = x360.register_notification().unwrap();
// In a loop or another thread:
if let Ok(Ok(notification)) = receiver.try_recv() {
println!("Player LED is now {}", notification.led_number);
}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}Sourcepub fn update(&self, report: &X360Report) -> Result<(), ClientError>
pub fn update(&self, report: &X360Report) -> Result<(), ClientError>
Submits an input state report for this Xbox 360 target.
This is the primary method for sending controller inputs to the system.
The provided X360Report contains the state of all buttons, triggers,
and thumbsticks.
§Warning
Calling this method immediately after plugging in the target will likely fail, as the system needs time to enumerate the device.
To reliably send updates right after creation, you must first call [wait_for_ready()].
§Example
let mut report = X360Report::default();
report.buttons = X360Button::A | X360Button::START;
report.thumb_lx = 16384; // Move left stick right
x360.update(&report)?;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 TargetHandle<DualShock4>
impl TargetHandle<DualShock4>
Sourcepub fn wait_for_ready(&self) -> Result<(), ClientError>
pub fn wait_for_ready(&self) -> Result<(), ClientError>
Blocks until the virtual controller is fully enumerated and ready to receive updates.
It is recommended to call this after plugging in a new controller if you want to immediately send a report to the controller.
§Example
use vigem_rust::{Client, Ds4Report};
let client = Client::connect().unwrap();
let ds4 = client.new_ds4_target().plugin().unwrap();
// Wait for the controller to be ready
ds4.wait_for_ready().unwrap();
// Now it's safe to send updates
ds4.update(&Ds4Report::default()).unwrap();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}Sourcepub fn register_notification(
&self,
) -> Result<Receiver<Result<Ds4Notification, BusError>>, ClientError>
pub fn register_notification( &self, ) -> Result<Receiver<Result<Ds4Notification, BusError>>, ClientError>
Registers to receive notifications for this DualShock 4 target.
This returns a Receiver that will yield Ds4Notifications from the bus,
which contain information like rumble data and lightbar color commands.
§Important
Calling this function spawns a dedicated background thread that lives as long as
the Receiver does.
§Example
let receiver = ds4.register_notification().unwrap();
// In a loop or another thread:
if let Ok(Ok(notification)) = receiver.try_recv() {
println!("Lightbar color changed to: {:?}", notification.lightbar);
}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}Sourcepub fn register_notification_raw_buffer(
&self,
) -> Result<Receiver<Result<Ds4OutputBuffer, BusError>>, ClientError>
pub fn register_notification_raw_buffer( &self, ) -> Result<Receiver<Result<Ds4OutputBuffer, BusError>>, ClientError>
Subscribes to raw 64-byte output buffers for a DualShock 4 target.
§Warning
Unlike the register_notification method, this one gets the raw
output buffer of all connected Dualshock 4 virtual controllers
via a single thread (centralized system.)
§Important
Calling this function spawns a dedicated background thread that lives as long as
the Receiver does.
This is an advanced function for applications that need to parse the raw output
report from the bus, which may contain more detailed information than the standard
Ds4Notification.
Sourcepub fn update(&self, report: &Ds4Report) -> Result<(), ClientError>
pub fn update(&self, report: &Ds4Report) -> Result<(), ClientError>
Submits a standard input state report for this DualShock 4 target.
This method sends a Ds4Report, which covers the state of all buttons,
D-Pad, triggers, and thumbsticks. For advanced features like touchpad or
motion sensor data, use update_ex instead.
§Warning
Calling this method immediately after plugging in the target will likely fail, as the system needs time to enumerate the device.
To reliably send updates right after creation, you must first call [wait_for_ready()].
§Example
let mut report = Ds4Report::default();
report.buttons = Ds4Button::CROSS.bits();
report.set_dpad(Ds4Dpad::South);
report.trigger_r = 255;
ds4.update(&report)?;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}Sourcepub fn update_ex(&self, report: &Ds4ReportEx) -> Result<(), ClientError>
pub fn update_ex(&self, report: &Ds4ReportEx) -> Result<(), ClientError>
Submits an extended input state report for this DualShock 4 target.
This method is used for advanced scenarios that require simulating motion
controls (gyroscope/accelerometer) and detailed touchpad activity. It sends
a Ds4ReportEx, which is a superset of the standard Ds4Report.
§Warning
Calling this method immediately after plugging in the target will likely fail, as the system needs time to enumerate the device.
To reliably send updates right after creation, you must first call [wait_for_ready()].
§Example
let mut report_ex = Ds4ReportEx::default();
// Set gyro data
report_ex.gyro_x = 12345;
// The standard report fields are also available
report_ex.thumb_lx = 200;
ds4.update_ex(&report_ex)?;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}Trait Implementations§
Source§impl<T: Clone> Clone for TargetHandle<T>
impl<T: Clone> Clone for TargetHandle<T>
Source§fn clone(&self) -> TargetHandle<T>
fn clone(&self) -> TargetHandle<T>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more