Added cool file parsing QoL features and some arguments to make this actually usable
This commit is contained in:
parent
9924e9b0cb
commit
b316c547de
8 changed files with 116 additions and 18 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
debug/
|
||||||
|
target/
|
||||||
|
**/*.rs.bk
|
||||||
|
*.pdb
|
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -379,6 +379,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac"
|
checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -393,6 +394,18 @@ dependencies = [
|
||||||
"strsim",
|
"strsim",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.5.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.77",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_lex"
|
name = "clap_lex"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
|
|
|
@ -8,7 +8,7 @@ license = "GPL-3.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.17", features = ["cargo"] }
|
clap = { version = "4.5.17", features = ["derive"] }
|
||||||
image = "0.25.2"
|
image = "0.25.2"
|
||||||
piston = "1.0.0"
|
piston = "1.0.0"
|
||||||
piston2d-graphics = "0.44.0"
|
piston2d-graphics = "0.44.0"
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
use std::fs::{self, read, File};
|
use std::{ffi::OsStr, fs::{self, read, File}, os::raw, path::Path};
|
||||||
use image::ImageReader;
|
use image::{ImageFormat, ImageReader};
|
||||||
use unreal_asset::{asset::AssetTrait, cast, engine_version::EngineVersion, exports::{self, normal_export::NormalExport, Export, ExportBaseTrait}, properties::{array_property::ArrayProperty, color_property::ColorProperty, struct_property::StructProperty, Property}, types::{fname::FNameContainer, PackageIndex}, Asset};
|
use unreal_asset::{asset::AssetTrait, cast, engine_version::EngineVersion, exports::{self, normal_export::NormalExport, Export, ExportBaseTrait}, properties::{array_property::ArrayProperty, color_property::ColorProperty, struct_property::StructProperty, Property}, types::{fname::FNameContainer, PackageIndex}, Asset};
|
||||||
|
|
||||||
pub fn rawrgb(path: &str) -> Result<Vec<u8>, String> {
|
fn rawrgb(path: &str) -> Result<Vec<u8>, String> {
|
||||||
match fs::read(path) {
|
match fs::read(path) {
|
||||||
Ok(res) => Ok(res),
|
Ok(res) => Ok(res),
|
||||||
Err(e) => Err(e.to_string()),
|
Err(e) => Err(e.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn image(path: &str) -> Result<Vec<u8>, String> {
|
fn image(path: &str) -> Result<Vec<u8>, String> {
|
||||||
match image::ImageReader::open(path) {
|
match image::ImageReader::open(path) {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
match res.decode() {
|
match res.decode() {
|
||||||
|
@ -23,8 +23,8 @@ pub fn image(path: &str) -> Result<Vec<u8>, String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Shitty formats = Shitty code
|
||||||
pub fn uasset(path: &str) -> Result<Vec<u8>, String> {
|
fn uasset(path: &str) -> Result<Vec<u8>, String> {
|
||||||
let Some(path) = path.strip_suffix(".uasset") else {
|
let Some(path) = path.strip_suffix(".uasset") else {
|
||||||
return Err("File not .uasset".to_string())
|
return Err("File not .uasset".to_string())
|
||||||
};
|
};
|
||||||
|
@ -77,3 +77,18 @@ pub fn uasset(path: &str) -> Result<Vec<u8>, String> {
|
||||||
}
|
}
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse(path: &str) -> Result<Vec<u8>, String> {
|
||||||
|
match Path::new(path).extension().and_then(OsStr::to_str) {
|
||||||
|
Some(s) => {
|
||||||
|
if s == "uasset" {
|
||||||
|
uasset(path)
|
||||||
|
} else if ImageFormat::from_extension(s).is_some() {
|
||||||
|
image(path)
|
||||||
|
} else {
|
||||||
|
rawrgb(path)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => rawrgb(path),
|
||||||
|
}
|
||||||
|
}
|
15
src/input.rs
15
src/input.rs
|
@ -1,5 +1,5 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
use std::{io::Read, net::UdpSocket, sync::mpsc::{self, Receiver, Sender}, thread, time::{Duration, Instant}};
|
use std::{io::Read, net::UdpSocket, sync::mpsc::{self, Receiver, Sender}, thread, time::{Duration, Instant}};
|
||||||
|
|
||||||
use crate::{ parser, fileparser };
|
use crate::{ parser, fileparser };
|
||||||
|
|
||||||
pub fn stdin(tx: Sender<Vec<[f32; 4]>>) {
|
pub fn stdin(tx: Sender<Vec<[f32; 4]>>) {
|
||||||
|
@ -23,7 +23,7 @@ pub fn stdin(tx: Sender<Vec<[f32; 4]>>) {
|
||||||
let _ = tx.send(r);
|
let _ = tx.send(r);
|
||||||
},
|
},
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
std::process::exit(0x0100);
|
std::process::exit(0);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,9 @@ pub fn realtimeudp(tx: Sender<Vec<[f32; 4]>>) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file(tx: Sender<Vec<[f32; 4]>>) {
|
pub fn file(tx: Sender<Vec<[f32; 4]>>, path: String) {
|
||||||
thread::spawn( move || {
|
thread::spawn( move || {
|
||||||
let Ok(rawbytes) = fileparser::rawrgb("out.raw.lily") else {
|
let Ok(rawbytes) = fileparser::parse(&path) else {
|
||||||
std::process::exit(1)
|
std::process::exit(1)
|
||||||
};
|
};
|
||||||
for frame in rawbytes.chunks(720) {
|
for frame in rawbytes.chunks(720) {
|
||||||
|
@ -58,3 +58,10 @@ pub fn file(tx: Sender<Vec<[f32; 4]>>) {
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(clap::ValueEnum, Clone, Debug)]
|
||||||
|
pub enum Input {
|
||||||
|
stdin,
|
||||||
|
realtimeudp,
|
||||||
|
file,
|
||||||
|
}
|
||||||
|
|
47
src/main.rs
47
src/main.rs
|
@ -6,9 +6,27 @@ mod utils;
|
||||||
mod fileparser;
|
mod fileparser;
|
||||||
|
|
||||||
use std::sync::mpsc::{self, Receiver, Sender};
|
use std::sync::mpsc::{self, Receiver, Sender};
|
||||||
use clap::{command, Parser};
|
use clap::{command, error::{self, ContextKind, ContextValue, ErrorKind}, Parser};
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[command(version, about, long_about = None)]
|
||||||
|
struct Args {
|
||||||
|
/// Name of the person to greet
|
||||||
|
#[arg(short, long)]
|
||||||
|
input: input::Input,
|
||||||
|
|
||||||
|
#[arg(required(false), short, long, requires = "input")]
|
||||||
|
file: Option<String>,
|
||||||
|
|
||||||
|
#[arg(short, long)]
|
||||||
|
output: output::Output,
|
||||||
|
|
||||||
|
#[arg(required(false), short, long, requires = "output")]
|
||||||
|
destip: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let args = Args::parse();
|
||||||
// let mut arg = clap::command!()
|
// let mut arg = clap::command!()
|
||||||
// .arg(clap::arg!(-o --output <file> "The output file to write to. Use - for stdout."))
|
// .arg(clap::arg!(-o --output <file> "The output file to write to. Use - for stdout."))
|
||||||
// .arg_required_else_help(true);
|
// .arg_required_else_help(true);
|
||||||
|
@ -19,8 +37,27 @@ fn main() {
|
||||||
// } else {
|
// } else {
|
||||||
// input::realtimeudp(tx)
|
// input::realtimeudp(tx)
|
||||||
// }
|
// }
|
||||||
input::file(tx);
|
match args.input {
|
||||||
output::realtimeudp(rx)
|
input::Input::stdin => input::stdin(tx),
|
||||||
|
input::Input::realtimeudp => input::realtimeudp(tx),
|
||||||
|
input::Input::file => {
|
||||||
|
if args.file.is_some() {
|
||||||
|
input::file(tx, args.file.unwrap());
|
||||||
|
} else {
|
||||||
|
utils::err_missing_args(vec!["--file".to_owned()])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// input::file(tx);
|
||||||
|
// output::piston(rx) 21324
|
||||||
|
match args.output {
|
||||||
|
output::Output::piston => output::piston(rx),
|
||||||
|
output::Output::realtimeudp => {
|
||||||
|
if args.destip.is_some() {
|
||||||
|
output::realtimeudp(rx, args.destip.unwrap())
|
||||||
|
} else {
|
||||||
|
utils::err_missing_args(vec!["--destip".to_owned()])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
extern crate piston_window;
|
extern crate piston_window;
|
||||||
|
|
||||||
use graphics;
|
use graphics;
|
||||||
|
@ -31,7 +32,7 @@ pub fn piston(rx: Receiver<Vec<[f32; 4]>>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn realtimeudp(rx: Receiver<Vec<[f32; 4]>>) {
|
pub fn realtimeudp(rx: Receiver<Vec<[f32; 4]>>, addr: String) {
|
||||||
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||||
loop {
|
loop {
|
||||||
let leds = rx.recv().unwrap();
|
let leds = rx.recv().unwrap();
|
||||||
|
@ -41,6 +42,18 @@ pub fn realtimeudp(rx: Receiver<Vec<[f32; 4]>>) {
|
||||||
packet.push((led[1]*255.0) as u8);
|
packet.push((led[1]*255.0) as u8);
|
||||||
packet.push((led[2]*255.0) as u8);
|
packet.push((led[2]*255.0) as u8);
|
||||||
}
|
}
|
||||||
let _ = socket.send_to(&packet, SocketAddr::from(([204, 2, 68, 140 ], 21324))).unwrap();
|
match socket.send_to(&packet, &addr) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(err) => {
|
||||||
|
println!("Error while sending trying to send data: {}", err);
|
||||||
|
std::process::exit(1);
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(clap::ValueEnum, Clone, Debug)]
|
||||||
|
pub enum Output {
|
||||||
|
piston,
|
||||||
|
realtimeudp,
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
use clap::error::{ContextKind, ContextValue, ErrorKind};
|
||||||
|
|
||||||
pub fn compare(a: f64, b: f64) -> f64 {
|
pub fn compare(a: f64, b: f64) -> f64 {
|
||||||
if a > b {
|
if a > b {
|
||||||
b
|
b
|
||||||
|
@ -16,4 +18,11 @@ pub fn offset(n: i16, max: i16, offset: i16) -> i16 {
|
||||||
|
|
||||||
pub fn scaleu8tof32(old_value: u8) -> f32 { // Convert a u8 between 0 and 255 to a f32 between 0.0 and 1.0 for piston colors
|
pub fn scaleu8tof32(old_value: u8) -> f32 { // Convert a u8 between 0 and 255 to a f32 between 0.0 and 1.0 for piston colors
|
||||||
(((old_value as f32 - 0.0) * (0.0 - 1.0)) / (0.0 - 255.0)) + 0.0
|
(((old_value as f32 - 0.0) * (0.0 - 1.0)) / (0.0 - 255.0)) + 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn err_missing_args(args: Vec<String>) {
|
||||||
|
let mut err = clap::Error::new(ErrorKind::MissingRequiredArgument);
|
||||||
|
err.insert(ContextKind::InvalidArg, ContextValue::Strings(args));
|
||||||
|
let _ = err.print();
|
||||||
|
std::process::exit(1);
|
||||||
}
|
}
|
Loading…
Reference in a new issue