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. 188
      ctru-rs/examples/ir-user.rs
  2. 7
      ctru-rs/src/error.rs
  3. 16
      ctru-rs/src/services/ir_user.rs

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

@ -1,8 +1,7 @@ @@ -1,8 +1,7 @@
use ctru::error::ResultCode;
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 time::Duration;
use std::time::Duration;
const PACKET_INFO_SIZE: usize = 8;
const MAX_PACKET_SIZE: usize = 32;
@ -42,115 +41,84 @@ fn main() { @@ -42,115 +41,84 @@ fn main() {
.expect("Couldn't get ir:USER recv event");
print_status_info();
// // Wait for the connection to establish
// (|| 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;
let mut is_connected = false;
'main_loop: while apt.main_loop() {
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 hid.keys_held().contains(KeyPad::KEY_START) {
break;
}
if check_ir_packet {
// Check if we've received a packet from the circle pad pro
let packet_received = IrUser::wait_for_event(recv_event, Duration::ZERO).is_ok();
if packet_received {
handle_packet(&ir_user, &top_console, &bottom_console);
}
if hid.keys_held().contains(KeyPad::KEY_START) {
break;
}
if hid.keys_down().contains(KeyPad::KEY_A) && !is_connected {
// Connection loop
loop {
hid.scan_input();
if hid.keys_held().contains(KeyPad::KEY_START) {
break 'main_loop;
}
if hid.keys_down().contains(KeyPad::KEY_A) {
match step {
0 => {
loop {
hid.scan_input();
if hid.keys_held().contains(KeyPad::KEY_START) {
break 'main_loop;
}
ir_user
.require_connection(IrDeviceId::CirclePadPro)
.expect("Couldn't initialize circle pad pro connection");
// Wait for the connection to establish
(|| unsafe {
ResultCode(ctru_sys::svcWaitSynchronization(
conn_status_event,
Duration::milliseconds(10).whole_nanoseconds() as i64,
))?;
Ok(())
})()
.expect("Failed to synchronize on connection status event");
print_status_info();
let status_info = ir_user.get_status_info();
if status_info.connection_status == 2 {
println!("Connected!");
break;
}
ir_user
.disconnect()
.expect("Failed to disconnect circle pad pro connection");
// Wait for the disconnect to go through
(|| unsafe {
ResultCode(ctru_sys::svcWaitSynchronization(
conn_status_event,
Duration::milliseconds(10).whole_nanoseconds() as i64,
))?;
Ok(())
})()
.expect("Failed to synchronize on connection status event");
ir_user
.require_connection(IrDeviceId::CirclePadPro)
.expect("Couldn't initialize circle pad pro connection");
// Wait for the connection to establish
if let Err(e) = IrUser::wait_for_event(conn_status_event, Duration::from_millis(100))
{
if !e.is_timeout() {
panic!("Couldn't initialize circle pad pro connection: {e}");
}
// }
// _ => {
loop {
hid.scan_input();
if hid.keys_held().contains(KeyPad::KEY_START) {
break 'main_loop;
}
if let Err(e) =
ir_user.start_polling_input(CPP_CONNECTION_POLLING_PERIOD_MS)
{
println!("Error: {e:?}");
}
print_status_info();
let check_ir_packet = unsafe {
ctru_sys::svcWaitSynchronization(
recv_event,
Duration::milliseconds(10).whole_nanoseconds() as i64,
) == 0
};
print_status_info();
if check_ir_packet {
println!("Got packet from CPP");
handle_packet(&ir_user, &top_console, &bottom_console);
break;
}
}
print_status_info();
let status_info = ir_user.get_status_info();
if status_info.connection_status == 2 {
println!("Connected!");
break;
}
ir_user
.disconnect()
.expect("Failed to disconnect circle pad pro connection");
// Wait for the disconnect to go through
if let Err(e) = IrUser::wait_for_event(conn_status_event, Duration::from_millis(100))
{
if !e.is_timeout() {
panic!("Couldn't initialize circle pad pro connection: {e}");
}
}
_ => {}
}
step += 1;
// Sending first packet retry loop
loop {
hid.scan_input();
if hid.keys_held().contains(KeyPad::KEY_START) {
break 'main_loop;
}
if let Err(e) = ir_user.start_polling_input(CPP_CONNECTION_POLLING_PERIOD_MS) {
println!("Error: {e:?}");
}
print_status_info();
let recv_event_result =
IrUser::wait_for_event(recv_event, Duration::from_millis(100));
print_status_info();
if recv_event_result.is_ok() {
println!("Got packet from CPP");
handle_packet(&ir_user, &top_console, &bottom_console);
break;
}
}
is_connected = true;
}
gfx.flush_buffers();
@ -163,6 +131,8 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso @@ -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)
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| {
writeln!(&mut output_buffer, "ReceiveBufferInfo:").unwrap();
let mut counter = 0;
@ -170,7 +140,7 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso @@ -170,7 +140,7 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso
write!(&mut output_buffer, "{byte:02x} ").unwrap();
counter += 1;
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 @@ -180,28 +150,27 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso
write!(&mut output_buffer, "{byte:02x} ").unwrap();
counter += 1;
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 packet_count = packets.len();
writeln!(&mut output_buffer, "Packet count: {packet_count}").unwrap();
let last_packet = packets.pop().unwrap();
writeln!(&mut output_buffer, "Last packet:\n{last_packet:02x?}").unwrap();
bottom_console.select();
bottom_console.clear();
std::io::stdout().write_all(&output_buffer).unwrap();
writeln!(&mut output_buffer, "{last_packet:02x?}").unwrap();
// Use println in case this fails
let cpp_response = CirclePadProInputResponse::try_from(last_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();
// Done handling the packet, release it
@ -209,6 +178,7 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso @@ -209,6 +178,7 @@ fn handle_packet(ir_user: &IrUser, top_console: &Console, bottom_console: &Conso
.release_received_data(packet_count as u32)
.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) {
println!("Error: {e:?}");
}

7
ctru-rs/src/error.rs

@ -69,6 +69,13 @@ impl Error { @@ -69,6 +69,13 @@ impl Error {
// Copy out of the error string, since it may be changed by other libc calls later
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 {

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

@ -6,6 +6,7 @@ use std::cmp::max; @@ -6,6 +6,7 @@ use std::cmp::max;
use std::ffi::CString;
use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut};
use std::sync::Mutex;
use std::time::Duration;
static IR_USER_ACTIVE: Mutex<usize> = Mutex::new(0);
static IR_USER_STATE: Mutex<Option<IrUserState>> = Mutex::new(None);
@ -182,6 +183,16 @@ impl IrUser { @@ -182,6 +183,16 @@ impl IrUser {
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<()> {
let ir_request: [u8; 3] = [1, period_ms, (period_ms + 2) << 2];
self.send_service_request(
@ -280,7 +291,7 @@ impl IrUser { @@ -280,7 +291,7 @@ impl IrUser {
packet_info[7],
]) 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 packet_data_offset = &shared_mem
// [data_start_offset..data_start_offset + data_length];
@ -444,7 +455,8 @@ impl TryFrom<IrUserPacket> for CirclePadProInputResponse { @@ -444,7 +455,8 @@ impl TryFrom<IrUserPacket> for CirclePadProInputResponse {
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_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 zl_pressed = packet.payload[4] & 0x20 == 0;
let zr_pressed = packet.payload[4] & 0x40 == 0;

Loading…
Cancel
Save