Browse Source

Clean up some of the code and warnings

pull/129/head
AzureMarker 2 years ago committed by Mark Drobnak
parent
commit
d798f56ad9
No known key found for this signature in database
GPG Key ID: 47A133F3BF9D03D3
  1. 116
      ctru-rs/examples/ir-user.rs
  2. 7
      ctru-rs/src/error.rs
  3. 16
      ctru-rs/src/services/ir_user.rs

116
ctru-rs/examples/ir-user.rs

@ -1,8 +1,7 @@
use ctru::error::ResultCode;
use ctru::prelude::*; use ctru::prelude::*;
use ctru::services::ir_user::{CirclePadProInputResponse, IrDeviceId, IrUser, IrUserStatusInfo}; use ctru::services::ir_user::{CirclePadProInputResponse, IrDeviceId, IrUser};
use std::io::Write; use std::io::Write;
use time::Duration; use std::time::Duration;
const PACKET_INFO_SIZE: usize = 8; const PACKET_INFO_SIZE: usize = 8;
const MAX_PACKET_SIZE: usize = 32; const MAX_PACKET_SIZE: usize = 32;
@ -42,38 +41,22 @@ fn main() {
.expect("Couldn't get ir:USER recv event"); .expect("Couldn't get ir:USER recv event");
print_status_info(); print_status_info();
// // Wait for the connection to establish let mut is_connected = false;
// (|| unsafe {
// ResultCode(ctru_sys::svcWaitSynchronization(
// ir_user_connection_status_event,
// Duration::seconds(10).whole_nanoseconds() as i64,
// ))?;
//
// println!("Finished waiting on connection status event");
// println!("StatusInfo:\n{:#?}", ir_user.get_status_info());
//
// Ok(())
// })().expect("Failed to connect to circle pad pro");
let mut step = 0;
'main_loop: while apt.main_loop() { 'main_loop: while apt.main_loop() {
hid.scan_input(); hid.scan_input();
// Check if we've received a packet from the circle pad pro
let check_ir_packet = unsafe { ctru_sys::svcWaitSynchronization(recv_event, 0) == 0 };
if check_ir_packet {
handle_packet(&ir_user, &top_console, &bottom_console);
}
if hid.keys_held().contains(KeyPad::KEY_START) { if hid.keys_held().contains(KeyPad::KEY_START) {
break; break;
} }
if hid.keys_down().contains(KeyPad::KEY_A) { // Check if we've received a packet from the circle pad pro
match step { let packet_received = IrUser::wait_for_event(recv_event, Duration::ZERO).is_ok();
0 => { if packet_received {
handle_packet(&ir_user, &top_console, &bottom_console);
}
if hid.keys_down().contains(KeyPad::KEY_A) && !is_connected {
// Connection loop
loop { loop {
hid.scan_input(); hid.scan_input();
if hid.keys_held().contains(KeyPad::KEY_START) { if hid.keys_held().contains(KeyPad::KEY_START) {
@ -85,15 +68,12 @@ fn main() {
.expect("Couldn't initialize circle pad pro connection"); .expect("Couldn't initialize circle pad pro connection");
// Wait for the connection to establish // Wait for the connection to establish
(|| unsafe { if let Err(e) = IrUser::wait_for_event(conn_status_event, Duration::from_millis(100))
ResultCode(ctru_sys::svcWaitSynchronization( {
conn_status_event, if !e.is_timeout() {
Duration::milliseconds(10).whole_nanoseconds() as i64, panic!("Couldn't initialize circle pad pro connection: {e}");
))?; }
}
Ok(())
})()
.expect("Failed to synchronize on connection status event");
print_status_info(); print_status_info();
let status_info = ir_user.get_status_info(); let status_info = ir_user.get_status_info();
@ -107,50 +87,38 @@ fn main() {
.expect("Failed to disconnect circle pad pro connection"); .expect("Failed to disconnect circle pad pro connection");
// Wait for the disconnect to go through // Wait for the disconnect to go through
(|| unsafe { if let Err(e) = IrUser::wait_for_event(conn_status_event, Duration::from_millis(100))
ResultCode(ctru_sys::svcWaitSynchronization( {
conn_status_event, if !e.is_timeout() {
Duration::milliseconds(10).whole_nanoseconds() as i64, panic!("Couldn't initialize circle pad pro connection: {e}");
))?; }
}
Ok(()) }
})()
.expect("Failed to synchronize on connection status event"); // Sending first packet retry loop
}
// }
// _ => {
loop { loop {
hid.scan_input(); hid.scan_input();
if hid.keys_held().contains(KeyPad::KEY_START) { if hid.keys_held().contains(KeyPad::KEY_START) {
break 'main_loop; break 'main_loop;
} }
if let Err(e) = if let Err(e) = ir_user.start_polling_input(CPP_CONNECTION_POLLING_PERIOD_MS) {
ir_user.start_polling_input(CPP_CONNECTION_POLLING_PERIOD_MS)
{
println!("Error: {e:?}"); println!("Error: {e:?}");
} }
print_status_info(); print_status_info();
let check_ir_packet = unsafe { let recv_event_result =
ctru_sys::svcWaitSynchronization( IrUser::wait_for_event(recv_event, Duration::from_millis(100));
recv_event,
Duration::milliseconds(10).whole_nanoseconds() as i64,
) == 0
};
print_status_info(); print_status_info();
if check_ir_packet { if recv_event_result.is_ok() {
println!("Got packet from CPP"); println!("Got packet from CPP");
handle_packet(&ir_user, &top_console, &bottom_console); handle_packet(&ir_user, &top_console, &bottom_console);
break; break;
} }
} }
}
_ => {}
}
step += 1; is_connected = true;
} }
gfx.flush_buffers(); gfx.flush_buffers();
@ -163,6 +131,8 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso
// Use a buffer to avoid flickering the screen (write all output at once) // Use a buffer to avoid flickering the screen (write all output at once)
let mut output_buffer = Vec::with_capacity(0x1000); let mut output_buffer = Vec::with_capacity(0x1000);
writeln!(&mut output_buffer, "{:x?}", ir_user.get_status_info()).unwrap();
ir_user.process_shared_memory(|ir_mem| { ir_user.process_shared_memory(|ir_mem| {
writeln!(&mut output_buffer, "ReceiveBufferInfo:").unwrap(); writeln!(&mut output_buffer, "ReceiveBufferInfo:").unwrap();
let mut counter = 0; let mut counter = 0;
@ -170,7 +140,7 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso
write!(&mut output_buffer, "{byte:02x} ").unwrap(); write!(&mut output_buffer, "{byte:02x} ").unwrap();
counter += 1; counter += 1;
if counter % 12 == 0 { if counter % 12 == 0 {
writeln!(&mut output_buffer, "").unwrap(); writeln!(&mut output_buffer).unwrap();
} }
} }
@ -180,28 +150,27 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso
write!(&mut output_buffer, "{byte:02x} ").unwrap(); write!(&mut output_buffer, "{byte:02x} ").unwrap();
counter += 1; counter += 1;
if counter % 12 == 0 { if counter % 12 == 0 {
writeln!(&mut output_buffer, "").unwrap(); writeln!(&mut output_buffer).unwrap();
} }
} }
writeln!(&mut output_buffer, "").unwrap(); writeln!(&mut output_buffer).unwrap();
}); });
let mut packets = ir_user.get_packets(); let mut packets = ir_user.get_packets();
let packet_count = packets.len(); let packet_count = packets.len();
writeln!(&mut output_buffer, "Packet count: {packet_count}").unwrap(); writeln!(&mut output_buffer, "Packet count: {packet_count}").unwrap();
let last_packet = packets.pop().unwrap(); let last_packet = packets.pop().unwrap();
writeln!(&mut output_buffer, "Last packet:\n{last_packet:02x?}").unwrap(); writeln!(&mut output_buffer, "{last_packet:02x?}").unwrap();
bottom_console.select();
bottom_console.clear();
std::io::stdout().write_all(&output_buffer).unwrap();
// Use println in case this fails
let cpp_response = CirclePadProInputResponse::try_from(last_packet) let cpp_response = CirclePadProInputResponse::try_from(last_packet)
.expect("Failed to parse CPP response from IR packet"); .expect("Failed to parse CPP response from IR packet");
println!("CPP Response:\n{cpp_response:#02x?}"); writeln!(&mut output_buffer, "{cpp_response:#02x?}").unwrap();
// Write output to bottom screen
bottom_console.select();
bottom_console.clear();
std::io::stdout().write_all(&output_buffer).unwrap();
top_console.select(); top_console.select();
// Done handling the packet, release it // Done handling the packet, release it
@ -209,6 +178,7 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso
.release_received_data(packet_count as u32) .release_received_data(packet_count as u32)
.expect("Failed to release ir:USER packet"); .expect("Failed to release ir:USER packet");
// Remind the CPP that we're still listening
if let Err(e) = ir_user.start_polling_input(CPP_POLLING_PERIOD_MS) { if let Err(e) = ir_user.start_polling_input(CPP_POLLING_PERIOD_MS) {
println!("Error: {e:?}"); println!("Error: {e:?}");
} }

7
ctru-rs/src/error.rs

@ -69,6 +69,13 @@ impl Error {
// Copy out of the error string, since it may be changed by other libc calls later // Copy out of the error string, since it may be changed by other libc calls later
Self::Libc(error_str.to_string_lossy().into()) Self::Libc(error_str.to_string_lossy().into())
} }
pub fn is_timeout(&self) -> bool {
match *self {
Error::Os(code) => R_DESCRIPTION(code) == ctru_sys::RD_TIMEOUT as ctru_sys::Result,
_ => false,
}
}
} }
impl From<ctru_sys::Result> for Error { impl From<ctru_sys::Result> for Error {

16
ctru-rs/src/services/ir_user.rs

@ -6,6 +6,7 @@ use std::cmp::max;
use std::ffi::CString; use std::ffi::CString;
use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut}; use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut};
use std::sync::Mutex; use std::sync::Mutex;
use std::time::Duration;
static IR_USER_ACTIVE: Mutex<usize> = Mutex::new(0); static IR_USER_ACTIVE: Mutex<usize> = Mutex::new(0);
static IR_USER_STATE: Mutex<Option<IrUserState>> = Mutex::new(None); static IR_USER_STATE: Mutex<Option<IrUserState>> = Mutex::new(None);
@ -182,6 +183,16 @@ impl IrUser {
Ok(recv_event) Ok(recv_event)
} }
pub fn wait_for_event(event: Handle, timeout: Duration) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::svcWaitSynchronization(
event,
timeout.as_nanos() as i64,
))?;
}
Ok(())
}
pub fn start_polling_input(&self, period_ms: u8) -> crate::Result<()> { pub fn start_polling_input(&self, period_ms: u8) -> crate::Result<()> {
let ir_request: [u8; 3] = [1, period_ms, (period_ms + 2) << 2]; let ir_request: [u8; 3] = [1, period_ms, (period_ms + 2) << 2];
self.send_service_request( self.send_service_request(
@ -280,7 +291,7 @@ impl IrUser {
packet_info[7], packet_info[7],
]) as usize; ]) as usize;
let packet_info_section_size = (user_state.recv_packet_count * 8); let packet_info_section_size = user_state.recv_packet_count * 8;
// let data_start_offset = 0x20 + packet_info_section_size + offset_to_data_buffer; // let data_start_offset = 0x20 + packet_info_section_size + offset_to_data_buffer;
// let packet_data_offset = &shared_mem // let packet_data_offset = &shared_mem
// [data_start_offset..data_start_offset + data_length]; // [data_start_offset..data_start_offset + data_length];
@ -444,7 +455,8 @@ impl TryFrom<IrUserPacket> for CirclePadProInputResponse {
let response_id = packet.payload[0]; let response_id = packet.payload[0];
let c_stick_x = packet.payload[1] as u16 + (((packet.payload[2] & 0x0F) as u16) << 8); let c_stick_x = packet.payload[1] as u16 + (((packet.payload[2] & 0x0F) as u16) << 8);
let c_stick_y = (((packet.payload[2] & 0xF0) as u16) >> 4) + ((packet.payload[3] as u16) << 4); let c_stick_y =
(((packet.payload[2] & 0xF0) as u16) >> 4) + ((packet.payload[3] as u16) << 4);
let battery_level = packet.payload[4] & 0x1F; let battery_level = packet.payload[4] & 0x1F;
let zl_pressed = packet.payload[4] & 0x20 == 0; let zl_pressed = packet.payload[4] & 0x20 == 0;
let zr_pressed = packet.payload[4] & 0x40 == 0; let zr_pressed = packet.payload[4] & 0x40 == 0;

Loading…
Cancel
Save