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"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -393,6 +394,18 @@ dependencies = [
|
|||
"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]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.2"
|
||||
|
|
|
@ -8,7 +8,7 @@ license = "GPL-3.0"
|
|||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.17", features = ["cargo"] }
|
||||
clap = { version = "4.5.17", features = ["derive"] }
|
||||
image = "0.25.2"
|
||||
piston = "1.0.0"
|
||||
piston2d-graphics = "0.44.0"
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
use std::fs::{self, read, File};
|
||||
use image::ImageReader;
|
||||
use std::{ffi::OsStr, fs::{self, read, File}, os::raw, path::Path};
|
||||
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};
|
||||
|
||||
pub fn rawrgb(path: &str) -> Result<Vec<u8>, String> {
|
||||
fn rawrgb(path: &str) -> Result<Vec<u8>, String> {
|
||||
match fs::read(path) {
|
||||
Ok(res) => Ok(res),
|
||||
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) {
|
||||
Ok(res) => {
|
||||
match res.decode() {
|
||||
|
@ -23,8 +23,8 @@ pub fn image(path: &str) -> Result<Vec<u8>, String> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn uasset(path: &str) -> Result<Vec<u8>, String> {
|
||||
//Shitty formats = Shitty code
|
||||
fn uasset(path: &str) -> Result<Vec<u8>, String> {
|
||||
let Some(path) = path.strip_suffix(".uasset") else {
|
||||
return Err("File not .uasset".to_string())
|
||||
};
|
||||
|
@ -77,3 +77,18 @@ pub fn uasset(path: &str) -> Result<Vec<u8>, String> {
|
|||
}
|
||||
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 crate::{ parser, fileparser };
|
||||
|
||||
pub fn stdin(tx: Sender<Vec<[f32; 4]>>) {
|
||||
|
@ -23,7 +23,7 @@ pub fn stdin(tx: Sender<Vec<[f32; 4]>>) {
|
|||
let _ = tx.send(r);
|
||||
},
|
||||
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 || {
|
||||
let Ok(rawbytes) = fileparser::rawrgb("out.raw.lily") else {
|
||||
let Ok(rawbytes) = fileparser::parse(&path) else {
|
||||
std::process::exit(1)
|
||||
};
|
||||
for frame in rawbytes.chunks(720) {
|
||||
|
@ -58,3 +58,10 @@ pub fn file(tx: Sender<Vec<[f32; 4]>>) {
|
|||
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;
|
||||
|
||||
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() {
|
||||
let args = Args::parse();
|
||||
// let mut arg = clap::command!()
|
||||
// .arg(clap::arg!(-o --output <file> "The output file to write to. Use - for stdout."))
|
||||
// .arg_required_else_help(true);
|
||||
|
@ -19,8 +37,27 @@ fn main() {
|
|||
// } else {
|
||||
// input::realtimeudp(tx)
|
||||
// }
|
||||
input::file(tx);
|
||||
output::realtimeudp(rx)
|
||||
|
||||
|
||||
match args.input {
|
||||
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;
|
||||
|
||||
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();
|
||||
loop {
|
||||
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[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 {
|
||||
if a > b {
|
||||
b
|
||||
|
@ -17,3 +19,10 @@ 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
|
||||
(((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