main: Naming collision avoidance + arg parsing
This commit is contained in:
@@ -133,7 +133,7 @@ impl<'t, Ctx: rusb::UsbContext> Controller<'t, Ctx> {
|
||||
|
||||
// debug-print the header
|
||||
if self.verbose {
|
||||
println!("HEAD: {:02x?}", &buf[..16]);
|
||||
println!("CMD: {:02x?}\n => {:02x?}", command, &buf[..16]);
|
||||
}
|
||||
|
||||
let mut data = [0; 64];
|
||||
|
||||
68
src/main.rs
68
src/main.rs
@@ -1,5 +1,7 @@
|
||||
use std::{error::Error, fmt::Display, io::Write, path::Path, thread::sleep, time::Duration};
|
||||
|
||||
use auto_args::AutoArgs;
|
||||
|
||||
use procon2::{
|
||||
Controller,
|
||||
descriptor::{VID, pid},
|
||||
@@ -25,16 +27,16 @@ const PLAYER: [u8; 16] = [
|
||||
0b1010,
|
||||
];
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let (mut dump, mut verbose) = (false, false);
|
||||
#[derive(Debug, AutoArgs)]
|
||||
struct Args {
|
||||
/// Prints the sent and received messages
|
||||
verbose: bool,
|
||||
/// Dumps the firmware of all connected controllers
|
||||
dump: bool,
|
||||
}
|
||||
|
||||
for arg in std::env::args() {
|
||||
match arg.as_str() {
|
||||
"dump" => dump = true,
|
||||
"verbose" => verbose = true,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let Args { verbose, dump } = Args::from_args();
|
||||
|
||||
let mut devices = vec![];
|
||||
|
||||
@@ -53,20 +55,9 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
|
||||
if dump {
|
||||
for (player, device) in devices.iter().enumerate() {
|
||||
for device in &devices {
|
||||
let path = make_path(device)?;
|
||||
let controller = Controller::new(device).verbose(verbose);
|
||||
let descriptor = device.device().device_descriptor()?;
|
||||
let name = if let Some(nid) = descriptor.product_string_index() {
|
||||
device.read_string_descriptor_ascii(nid)?
|
||||
} else {
|
||||
String::from("procon")
|
||||
};
|
||||
let path = format!(
|
||||
"{name} {:04x}_{:04x}_{}-{player:x}.bin",
|
||||
descriptor.vendor_id(),
|
||||
descriptor.product_id(),
|
||||
descriptor.device_version()
|
||||
);
|
||||
procon_dump(controller, path)?;
|
||||
}
|
||||
return Ok(());
|
||||
@@ -92,6 +83,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Dumps a Controller's firmware to a file at the given path
|
||||
fn procon_dump<Ctx: rusb::UsbContext>(
|
||||
controller: Controller<'_, Ctx>,
|
||||
path: impl AsRef<Path> + Display,
|
||||
@@ -105,11 +97,12 @@ fn procon_dump<Ctx: rusb::UsbContext>(
|
||||
file.write_all(&data)?;
|
||||
|
||||
// progress bar
|
||||
if addr % 0x8000 == 0 {
|
||||
controller.set_player_led(PLAYER[7 - (addr >> 15 & 7)])?;
|
||||
if addr % 0x40000 == 0 {
|
||||
print!(".");
|
||||
std::io::stdout().flush()?;
|
||||
sleep(Duration::from_millis(0));
|
||||
}
|
||||
if addr % 0x8000 == 0 {
|
||||
controller.set_player_led(PLAYER[7 - ((addr / 0x8000) & 7)])?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,3 +110,28 @@ fn procon_dump<Ctx: rusb::UsbContext>(
|
||||
println!("\nDumped to file {path}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates a path to store a given device's firmware at, avoiding naming collisions
|
||||
fn make_path<Ctx: rusb::UsbContext>(device: &rusb::DeviceHandle<Ctx>) -> rusb::Result<String> {
|
||||
let descriptor = device.device().device_descriptor()?;
|
||||
let name = match descriptor.product_string_index() {
|
||||
Some(nid) => device.read_string_descriptor_ascii(nid)?,
|
||||
None => String::from("procon"),
|
||||
};
|
||||
|
||||
let path = format!(
|
||||
"{name} {:04x}_{:04x}_{}",
|
||||
descriptor.vendor_id(),
|
||||
descriptor.product_id(),
|
||||
descriptor.device_version()
|
||||
);
|
||||
|
||||
let mut count = 1;
|
||||
let mut out_path = format!("{path}.bin");
|
||||
while std::fs::exists(&out_path).unwrap_or(true) {
|
||||
out_path = format!("{path}({count}).bin");
|
||||
count += 1;
|
||||
}
|
||||
|
||||
Ok(out_path)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user