main: Naming collision avoidance + arg parsing
This commit is contained in:
parent
8b56a1bc5d
commit
0bb97b167f
56
Cargo.lock
generated
56
Cargo.lock
generated
@ -2,6 +2,26 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "auto-args"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40797fd8889b7625595cb391d6f8428802b65c22023ada3dc08d67953ac5e5e2"
|
||||
dependencies = [
|
||||
"auto-args-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "auto-args-derive"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d4cbc684c4d4c80b06cd1009b7b78fe5a910187d1daeda1cc04319207b5894f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.31"
|
||||
@ -35,13 +55,32 @@ version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "procon2"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"auto-args",
|
||||
"rusb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusb"
|
||||
version = "0.9.4"
|
||||
@ -58,6 +97,23 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
@ -4,4 +4,5 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
auto-args = "0.3.2"
|
||||
rusb = "0.9.4"
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user