Replace array_chunks feature and refactoring
This commit is contained in:
parent
31035b9c92
commit
4f959d217d
15 changed files with 213 additions and 176 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -1,6 +1,6 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ELApse"
|
name = "ELApse"
|
||||||
|
@ -10,6 +10,7 @@ dependencies = [
|
||||||
"ftdi-embedded-hal",
|
"ftdi-embedded-hal",
|
||||||
"image",
|
"image",
|
||||||
"piston_window",
|
"piston_window",
|
||||||
|
"rgb",
|
||||||
"unreal_asset",
|
"unreal_asset",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
@ -1857,9 +1858,9 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rgb"
|
name = "rgb"
|
||||||
version = "0.8.50"
|
version = "0.8.52"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
|
checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
@ -2297,13 +2298,6 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "usbintled"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"ELApse",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
|
@ -12,6 +12,7 @@ clap = { version = "4.5.17", features = ["derive"] }
|
||||||
ftdi-embedded-hal = { version = "0.22.0", features = ["libftd2xx"] }
|
ftdi-embedded-hal = { version = "0.22.0", features = ["libftd2xx"] }
|
||||||
image = "0.25.2"
|
image = "0.25.2"
|
||||||
piston_window = "0.132.0"
|
piston_window = "0.132.0"
|
||||||
|
rgb = "0.8.52"
|
||||||
unreal_asset = "0.1.16"
|
unreal_asset = "0.1.16"
|
||||||
url = "2.5.2"
|
url = "2.5.2"
|
||||||
|
|
||||||
|
@ -23,9 +24,6 @@ opt-level = 3
|
||||||
inherits = "release"
|
inherits = "release"
|
||||||
lto = "thin"
|
lto = "thin"
|
||||||
|
|
||||||
[workspace]
|
|
||||||
members = ["usbintled"]
|
|
||||||
|
|
||||||
# Config for 'cargo dist'
|
# Config for 'cargo dist'
|
||||||
[workspace.metadata.dist]
|
[workspace.metadata.dist]
|
||||||
# The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax)
|
# The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax)
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[toolchain]
|
|
||||||
channel = "nightly"
|
|
61
src/input.rs
61
src/input.rs
|
@ -1,61 +0,0 @@
|
||||||
#![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]>>) {
|
|
||||||
let (stdintx, stdinrx): (Sender<Vec<u8>>, Receiver<Vec<u8>>) = mpsc::channel();
|
|
||||||
thread::spawn( move || {
|
|
||||||
let mut buf = [0; 1500];
|
|
||||||
let mut e = std::io::stdin().lock();
|
|
||||||
loop {
|
|
||||||
let amt = e.read(&mut buf).unwrap();
|
|
||||||
if buf[..amt].to_vec().len() > 0 {
|
|
||||||
let _ = stdintx.send(buf[..amt].to_vec());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
thread::spawn( move || {
|
|
||||||
loop {
|
|
||||||
// let amt = e.read(&mut buf).unwrap();
|
|
||||||
match stdinrx.recv_timeout(Duration::from_millis(500)) {
|
|
||||||
Ok(d) => {
|
|
||||||
let r: Vec<[f32; 4]> = parser::parseleds(d, parser::ParserOptions::default().mirror(true).double(true).offset(15));
|
|
||||||
let _ = tx.send(r);
|
|
||||||
},
|
|
||||||
Err(_) => {
|
|
||||||
std::process::exit(0);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn realtimeudp(tx: Sender<Vec<[f32; 4]>>,bindaddr: String) {
|
|
||||||
thread::spawn( move || {
|
|
||||||
let socket = UdpSocket::bind(bindaddr).unwrap();
|
|
||||||
let mut buf = [0; 1500];
|
|
||||||
loop {
|
|
||||||
let (amt, _src) = socket.recv_from(&mut buf).unwrap();
|
|
||||||
let r = parser::parseleds(buf[..amt].to_vec(), parser::ParserOptions::default().stripheader(2));
|
|
||||||
let _ = tx.send(r);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn file(tx: Sender<Vec<[f32; 4]>>, path: String) {
|
|
||||||
thread::spawn( move || {
|
|
||||||
let Ok(rawbytes) = fileparser::parse(&path) else {
|
|
||||||
println!("File not found");
|
|
||||||
std::process::exit(1)
|
|
||||||
};
|
|
||||||
for frame in rawbytes.chunks(720) {
|
|
||||||
let st = Instant::now();
|
|
||||||
let r = parser::parseleds(frame.to_vec(), parser::ParserOptions::default().mirror(true).double(true).offset(15));
|
|
||||||
let _ = tx.send(r);
|
|
||||||
if Duration::from_secs_f32(1.0/60.0) > st.elapsed() {
|
|
||||||
thread::sleep(Duration::from_secs_f32(1.0/60.0)-st.elapsed());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
std::process::exit(0);
|
|
||||||
});
|
|
||||||
}
|
|
29
src/input/file.rs
Normal file
29
src/input/file.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
use std::{sync::mpsc::Sender, thread, time::{Duration, Instant}};
|
||||||
|
use crate::{fileparser, input::Input, parser};
|
||||||
|
|
||||||
|
impl Input {
|
||||||
|
pub fn file(tx: Sender<Vec<[f32; 4]>>, path: String) {
|
||||||
|
thread::spawn(move || {
|
||||||
|
let Ok(rawbytes) = fileparser::parse(&path) else {
|
||||||
|
println!("File not found");
|
||||||
|
std::process::exit(1)
|
||||||
|
};
|
||||||
|
for frame in rawbytes.chunks(720) {
|
||||||
|
let st = Instant::now();
|
||||||
|
let r = parser::parseleds(
|
||||||
|
frame.to_vec(),
|
||||||
|
parser::ParserOptions::default()
|
||||||
|
.mirror(true)
|
||||||
|
.double(true)
|
||||||
|
.offset(15),
|
||||||
|
);
|
||||||
|
let _ = tx.send(r);
|
||||||
|
if Duration::from_secs_f32(1.0 / 60.0) > st.elapsed() {
|
||||||
|
thread::sleep(Duration::from_secs_f32(1.0 / 60.0) - st.elapsed());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
std::process::exit(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
5
src/input/mod.rs
Normal file
5
src/input/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
mod file;
|
||||||
|
mod realtimeudp;
|
||||||
|
mod stdin;
|
||||||
|
|
||||||
|
pub struct Input;
|
20
src/input/realtimeudp.rs
Normal file
20
src/input/realtimeudp.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
use std::{net::UdpSocket, sync::mpsc::Sender, thread};
|
||||||
|
use crate::{input::Input, parser};
|
||||||
|
|
||||||
|
impl Input {
|
||||||
|
pub fn realtimeudp(tx: Sender<Vec<[f32; 4]>>, bindaddr: String) {
|
||||||
|
thread::spawn(move || {
|
||||||
|
let socket = UdpSocket::bind(bindaddr).unwrap();
|
||||||
|
let mut buf = [0; 1500];
|
||||||
|
loop {
|
||||||
|
let (amt, _src) = socket.recv_from(&mut buf).unwrap();
|
||||||
|
let r = parser::parseleds(
|
||||||
|
buf[..amt].to_vec(),
|
||||||
|
parser::ParserOptions::default().stripheader(2),
|
||||||
|
);
|
||||||
|
let _ = tx.send(r);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
39
src/input/stdin.rs
Normal file
39
src/input/stdin.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
use std::{io::Read, sync::mpsc::{self, Receiver, Sender}, thread, time::Duration};
|
||||||
|
use crate::{input::Input, parser};
|
||||||
|
|
||||||
|
impl Input {
|
||||||
|
pub fn stdin(tx: Sender<Vec<[f32; 4]>>) {
|
||||||
|
let (stdintx, stdinrx): (Sender<Vec<u8>>, Receiver<Vec<u8>>) = mpsc::channel();
|
||||||
|
thread::spawn(move || {
|
||||||
|
let mut buf = [0; 1500];
|
||||||
|
let mut e = std::io::stdin().lock();
|
||||||
|
loop {
|
||||||
|
let amt = e.read(&mut buf).unwrap();
|
||||||
|
if buf[..amt].to_vec().len() > 0 {
|
||||||
|
let _ = stdintx.send(buf[..amt].to_vec());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread::spawn(move || {
|
||||||
|
loop {
|
||||||
|
// let amt = e.read(&mut buf).unwrap();
|
||||||
|
match stdinrx.recv_timeout(Duration::from_millis(500)) {
|
||||||
|
Ok(d) => {
|
||||||
|
let r: Vec<[f32; 4]> = parser::parseleds(
|
||||||
|
d,
|
||||||
|
parser::ParserOptions::default()
|
||||||
|
.mirror(true)
|
||||||
|
.double(true)
|
||||||
|
.offset(15),
|
||||||
|
);
|
||||||
|
let _ = tx.send(r);
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
17
src/main.rs
17
src/main.rs
|
@ -1,4 +1,3 @@
|
||||||
#![feature(array_chunks)]
|
|
||||||
mod input;
|
mod input;
|
||||||
mod output;
|
mod output;
|
||||||
mod parser;
|
mod parser;
|
||||||
|
@ -8,6 +7,8 @@ mod fileparser;
|
||||||
use std::sync::mpsc::{self, Receiver, Sender};
|
use std::sync::mpsc::{self, Receiver, Sender};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
use crate::output::Output;
|
||||||
|
use crate::input::Input;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(version, about, long_about = None)]
|
#[command(version, about, long_about = None)]
|
||||||
|
@ -25,15 +26,15 @@ fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let (tx, rx): (Sender<Vec<[f32; 4]>>, Receiver<Vec<[f32; 4]>>) = mpsc::channel();
|
let (tx, rx): (Sender<Vec<[f32; 4]>>, Receiver<Vec<[f32; 4]>>) = mpsc::channel();
|
||||||
match args.input.as_str() {
|
match args.input.as_str() {
|
||||||
"-" | "stdin" => input::stdin(tx),
|
"-" | "stdin" => Input::stdin(tx),
|
||||||
_ => {
|
_ => {
|
||||||
match Url::parse(&args.input) {
|
match Url::parse(&args.input) {
|
||||||
Ok(o) => {
|
Ok(o) => {
|
||||||
match o.scheme() {
|
match o.scheme() {
|
||||||
"udp" => {
|
"udp" => {
|
||||||
input::realtimeudp(tx, utils::get_host(o));
|
Input::realtimeudp(tx, utils::get_host(o));
|
||||||
},
|
},
|
||||||
"file" => input::file(tx, o.path().to_owned()),
|
"file" => Input::file(tx, o.path().to_owned()),
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unrecognized uri scheme");
|
println!("Unrecognized uri scheme");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
|
@ -41,19 +42,19 @@ fn main() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
input::file(tx, args.input);
|
Input::file(tx, args.input);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match args.output.as_str() {
|
match args.output.as_str() {
|
||||||
"piston" => output::piston(rx),
|
"piston" => Output::piston(rx),
|
||||||
"ftd2xx" => output::ft2dxx(rx),
|
"ftd2xx" => Output::ft2dxx(rx),
|
||||||
_ => {
|
_ => {
|
||||||
match Url::parse(&args.output) {
|
match Url::parse(&args.output) {
|
||||||
Ok(o) => {
|
Ok(o) => {
|
||||||
match o.scheme() {
|
match o.scheme() {
|
||||||
"udp" => output::realtimeudp(rx,utils::get_host(o)),
|
"udp" => Output::realtimeudp(rx,utils::get_host(o)),
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unrecognized uri scheme");
|
println!("Unrecognized uri scheme");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
|
|
||||||
use piston_window::*;
|
|
||||||
use piston_window::graphics::math::Scalar;
|
|
||||||
use std::{net::UdpSocket, sync::mpsc::Receiver, time::Duration};
|
|
||||||
|
|
||||||
use ftdi_embedded_hal::eh0::prelude::_embedded_hal_blocking_spi_Write;
|
|
||||||
use ftdi_embedded_hal::{self as hal, libftd2xx};
|
|
||||||
|
|
||||||
use crate::utils::{compare, offset};
|
|
||||||
|
|
||||||
pub fn piston(rx: Receiver<Vec<[f32; 4]>>) {
|
|
||||||
let mut window: PistonWindow =
|
|
||||||
WindowSettings::new("ELApse", [800, 800])
|
|
||||||
.transparent(true)
|
|
||||||
.exit_on_esc(true).build().unwrap();
|
|
||||||
while let Some(e) = window.next() {
|
|
||||||
let r = match rx.recv_timeout(Duration::from_millis(66)) {
|
|
||||||
Ok(e) => e,
|
|
||||||
Err(_) => vec![[0.02, 0.02, 0.02, 1.0]; 480],
|
|
||||||
};
|
|
||||||
|
|
||||||
let size = window.size();
|
|
||||||
let wh = compare(size.height, size.width)*0.75;
|
|
||||||
window.draw_2d(&e, |c, g, _device| {
|
|
||||||
for e in 1..9 {
|
|
||||||
for i in 0..60 {
|
|
||||||
let rwh = wh*(1.0-(e as f64*0.06));
|
|
||||||
circle_arc(r[i*8+(e-1)], rwh/32.0, Scalar::deg_to_rad(offset((((360/60)*i)) as i16, 360, 90) as f64), Scalar::deg_to_rad(offset((((360/60)*i)+6) as i16, 360, 90) as f64), [(size.width/2.0)-(rwh/2.0), (size.height/2.0)-(rwh/2.0), rwh, rwh], c.transform, g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
let mut packet: Vec<u8> = vec![2, 2];
|
|
||||||
for led in leds {
|
|
||||||
packet.push((led[0]*255.0) as u8);
|
|
||||||
packet.push((led[1]*255.0) as u8);
|
|
||||||
packet.push((led[2]*255.0) as u8);
|
|
||||||
}
|
|
||||||
match socket.send_to(&packet, &addr) {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(err) => {
|
|
||||||
println!("Error while sending trying to send data: {}", err);
|
|
||||||
std::process::exit(1);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ft2dxx(rx: Receiver<Vec<[f32; 4]>>) {
|
|
||||||
let device = libftd2xx::Ft232h::with_description("Single RS232-HS").unwrap();
|
|
||||||
println!("Connected to FT232H");
|
|
||||||
|
|
||||||
let hal = hal::FtHal::init_freq(device, 3_000_000).unwrap();
|
|
||||||
let mut spi = hal.spi().unwrap();
|
|
||||||
|
|
||||||
// led stuff
|
|
||||||
loop {
|
|
||||||
let leds = rx.recv().unwrap();
|
|
||||||
let mut fdata: Vec<u8> = Vec::new();
|
|
||||||
for led in leds {
|
|
||||||
let sled = [led[1],led[0],led[2]]; //Shift colors (be gone when I make a color struct)
|
|
||||||
for i in 0..3 {
|
|
||||||
let mut data = (sled[i].clone()*255.0) as u8;
|
|
||||||
let patterns = [0b1000_1000, 0b1000_1110, 0b11101000, 0b11101110];
|
|
||||||
for _ in 0..4 {
|
|
||||||
let bits = (data & 0b1100_0000) >> 6;
|
|
||||||
fdata.push(patterns[bits as usize]);
|
|
||||||
data <<= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let _ = spi.write(&fdata);
|
|
||||||
// for _ in 0..140 {
|
|
||||||
// spi.write(std::array::from_ref(&0)).unwrap();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(clap::ValueEnum, Clone, Debug)]
|
|
||||||
pub enum Output {
|
|
||||||
piston,
|
|
||||||
realtimeudp,
|
|
||||||
ft2dxx,
|
|
||||||
}
|
|
40
src/output/ft2dxx.rs
Normal file
40
src/output/ft2dxx.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
|
use std::sync::mpsc::Receiver;
|
||||||
|
|
||||||
|
use ftdi_embedded_hal::eh0::prelude::_embedded_hal_blocking_spi_Write;
|
||||||
|
use ftdi_embedded_hal::{self as hal, libftd2xx};
|
||||||
|
|
||||||
|
use crate::output::Output;
|
||||||
|
|
||||||
|
impl Output {
|
||||||
|
pub fn ft2dxx(rx: Receiver<Vec<[f32; 4]>>) {
|
||||||
|
let device = libftd2xx::Ft232h::with_description("Single RS232-HS").unwrap();
|
||||||
|
println!("Connected to FT232H");
|
||||||
|
|
||||||
|
let hal = hal::FtHal::init_freq(device, 3_000_000).unwrap();
|
||||||
|
let mut spi = hal.spi().unwrap();
|
||||||
|
|
||||||
|
// led stuff
|
||||||
|
loop {
|
||||||
|
let leds = rx.recv().unwrap();
|
||||||
|
let mut fdata: Vec<u8> = Vec::new();
|
||||||
|
for led in leds {
|
||||||
|
let sled = [led[1], led[0], led[2]]; //Shift colors (be gone when I make a color struct)
|
||||||
|
for i in 0..3 {
|
||||||
|
let mut data = (sled[i].clone() * 255.0) as u8;
|
||||||
|
let patterns = [0b1000_1000, 0b1000_1110, 0b11101000, 0b11101110];
|
||||||
|
for _ in 0..4 {
|
||||||
|
let bits = (data & 0b1100_0000) >> 6;
|
||||||
|
fdata.push(patterns[bits as usize]);
|
||||||
|
data <<= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _ = spi.write(&fdata);
|
||||||
|
// for _ in 0..140 {
|
||||||
|
// spi.write(std::array::from_ref(&0)).unwrap();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
src/output/mod.rs
Normal file
5
src/output/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
mod ft2dxx;
|
||||||
|
mod piston;
|
||||||
|
mod realtimeudp;
|
||||||
|
|
||||||
|
pub struct Output;
|
34
src/output/piston.rs
Normal file
34
src/output/piston.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
|
use piston_window::*;
|
||||||
|
use piston_window::graphics::math::Scalar;
|
||||||
|
use std::{sync::mpsc::Receiver, time::Duration};
|
||||||
|
|
||||||
|
use crate::output::Output;
|
||||||
|
use crate::utils::{compare, offset};
|
||||||
|
|
||||||
|
impl Output {
|
||||||
|
pub fn piston(rx: Receiver<Vec<[f32; 4]>>) {
|
||||||
|
let mut window: PistonWindow =
|
||||||
|
WindowSettings::new("ELApse", [800, 800])
|
||||||
|
.transparent(true)
|
||||||
|
.exit_on_esc(true).build().unwrap();
|
||||||
|
while let Some(e) = window.next() {
|
||||||
|
let r = match rx.recv_timeout(Duration::from_millis(66)) {
|
||||||
|
Ok(e) => e,
|
||||||
|
Err(_) => vec![[0.02, 0.02, 0.02, 1.0]; 480],
|
||||||
|
};
|
||||||
|
|
||||||
|
let size = window.size();
|
||||||
|
let wh = compare(size.height, size.width)*0.75;
|
||||||
|
window.draw_2d(&e, |c, g, _device| {
|
||||||
|
for e in 1..9 {
|
||||||
|
for i in 0..60 {
|
||||||
|
let rwh = wh*(1.0-(e as f64*0.06));
|
||||||
|
circle_arc(r[i*8+(e-1)], rwh/32.0, Scalar::deg_to_rad(offset((((360/60)*i)) as i16, 360, 90) as f64), Scalar::deg_to_rad(offset((((360/60)*i)+6) as i16, 360, 90) as f64), [(size.width/2.0)-(rwh/2.0), (size.height/2.0)-(rwh/2.0), rwh, rwh], c.transform, g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
src/output/realtimeudp.rs
Normal file
26
src/output/realtimeudp.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
use std::{net::UdpSocket, sync::mpsc::Receiver};
|
||||||
|
|
||||||
|
use crate::output::Output;
|
||||||
|
|
||||||
|
impl Output {
|
||||||
|
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();
|
||||||
|
let mut packet: Vec<u8> = vec![2, 2];
|
||||||
|
for led in leds {
|
||||||
|
packet.push((led[0] * 255.0) as u8);
|
||||||
|
packet.push((led[1] * 255.0) as u8);
|
||||||
|
packet.push((led[2] * 255.0) as u8);
|
||||||
|
}
|
||||||
|
match socket.send_to(&packet, &addr) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(err) => {
|
||||||
|
println!("Error while sending trying to send data: {}", err);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,7 +34,7 @@ pub fn parseleds(mut data: Vec<u8>, options: ParserOptions) -> Vec<[f32; 4]> {
|
||||||
if data.len() < expectedlen {
|
if data.len() < expectedlen {
|
||||||
data.append(&mut vec![5; expectedlen-out.len()]);
|
data.append(&mut vec![5; expectedlen-out.len()]);
|
||||||
}
|
}
|
||||||
for x in data.array_chunks::<3>() {
|
for x in data.as_chunks::<3>().0.iter() {
|
||||||
out.push([utils::scaleu8tof32(x[0]), utils::scaleu8tof32(x[1]), utils::scaleu8tof32(x[2]), 1.0]);
|
out.push([utils::scaleu8tof32(x[0]), utils::scaleu8tof32(x[1]), utils::scaleu8tof32(x[2]), 1.0]);
|
||||||
if options.double && !options.mirror {
|
if options.double && !options.mirror {
|
||||||
out.push(out.last().unwrap().clone());
|
out.push(out.last().unwrap().clone());
|
||||||
|
|
Loading…
Reference in a new issue