fading-tail #2
214
src/main.rs
214
src/main.rs
@@ -1,7 +1,8 @@
|
|||||||
use core::f32;
|
use core::f32;
|
||||||
use std::{io::stdin, time::Duration};
|
use std::time::Duration;
|
||||||
|
|
||||||
use macroquad::prelude::*;
|
use macroquad::prelude::*;
|
||||||
|
use serialport::SerialPort;
|
||||||
|
|
||||||
const THICKNESS: f32 = 2.0;
|
const THICKNESS: f32 = 2.0;
|
||||||
const TAIL_LEN: usize = 500;
|
const TAIL_LEN: usize = 500;
|
||||||
@@ -49,47 +50,66 @@ enum Axis {
|
|||||||
One,
|
One,
|
||||||
Two
|
Two
|
||||||
}
|
}
|
||||||
struct Tail {
|
|
||||||
|
/// # Graph
|
||||||
|
/// Holds 1 contiguous line. Can be graphed on 1 or 2 axis.
|
||||||
|
struct Graph {
|
||||||
points: [Point; TAIL_LEN],
|
points: [Point; TAIL_LEN],
|
||||||
head: usize,
|
head: usize,
|
||||||
axis: Axis,
|
axises: Axis,
|
||||||
/// What the tail treats as 0
|
/// What the tail treats as 0
|
||||||
x_offset: f32,
|
head_tracker: f32,
|
||||||
/// What the tail treats as 0
|
/// The graph's local origin
|
||||||
y_offset: f32,
|
x_origin: f32,
|
||||||
|
/// The graph's local origin
|
||||||
|
y_origin: f32,
|
||||||
/// How fast X scrolls when using a since axis tail
|
/// How fast X scrolls when using a since axis tail
|
||||||
px_per_s: f32,
|
px_per_s: f32,
|
||||||
}
|
}
|
||||||
impl Tail {
|
impl Graph {
|
||||||
fn new(axis: Axis, y_axis_offset: f32) -> Self {
|
fn new(axises: Axis) -> Self {
|
||||||
let (x_offset, y_offset) = match axis {
|
let (x_offset, y_offset) = match axises {
|
||||||
Axis::One => (0., y_axis_offset),
|
Axis::One => {
|
||||||
Axis::Two => (screen_width() /2., y_axis_offset),
|
(0., screen_height()*0.5)
|
||||||
|
},
|
||||||
|
Axis::Two => {
|
||||||
|
(screen_width()/2.,screen_height()/2.)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
// start all the dots off screen
|
// start all the dots off screen
|
||||||
points: [Point::new(-1.,-1.); TAIL_LEN],
|
points: [Point::new(-1.,-1.); TAIL_LEN],
|
||||||
head: 0,
|
head: 0,
|
||||||
axis,
|
axises,
|
||||||
x_offset,
|
x_origin: x_offset,
|
||||||
y_offset,
|
y_origin: y_offset,
|
||||||
px_per_s: 750.,
|
px_per_s: 750.,
|
||||||
|
head_tracker: 0.,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn place_next(&mut self, delta_time: f32, x_displace: f32, y_displace: f32) {
|
fn draw_axises(&self) {
|
||||||
match self.axis {
|
// Horzontal line
|
||||||
|
// (0, y_origin) -> (max, y_origin)
|
||||||
|
draw_line(0.,self.y_origin,screen_width(),self.y_origin,1.,DARKGRAY);
|
||||||
|
// Vertical line
|
||||||
|
// (x_origin, 0) -> (x_origin, max)
|
||||||
|
draw_line(self.x_origin,0.,self.x_origin,screen_height(),1.,DARKGRAY);
|
||||||
|
}
|
||||||
|
fn place_next(&mut self, delta_time: f32, x_displacement: f32, y_displacement: f32) {
|
||||||
|
match self.axises {
|
||||||
Axis::One => {
|
Axis::One => {
|
||||||
// x will scroll while y gets displaced
|
// x will scroll while y gets displaced
|
||||||
if self.x_offset >= screen_width() {
|
if self.head_tracker >= screen_width() {
|
||||||
self.x_offset = 0.;
|
self.head_tracker = 0.;
|
||||||
} else {
|
} else {
|
||||||
self.x_offset = self.x_offset + (delta_time * self.px_per_s)
|
self.head_tracker = self.head_tracker + (delta_time * self.px_per_s)
|
||||||
}
|
}
|
||||||
self.push(Point::new(self.x_offset, self.y_offset+y_displace));
|
self.push(Point::new(self.head_tracker, self.y_origin-y_displacement));
|
||||||
},
|
},
|
||||||
Axis::Two => {
|
Axis::Two => {
|
||||||
// both x and y will get displaced
|
// both x and y will get displaced
|
||||||
self.push(Point::new(self.x_offset+x_displace,self.y_offset+y_displace))
|
self.push(Point::new(self.x_origin+x_displacement,self.y_origin-y_displacement))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,27 +159,65 @@ impl Tail {
|
|||||||
};
|
};
|
||||||
self.points[prev]
|
self.points[prev]
|
||||||
}
|
}
|
||||||
fn points(&self) -> usize {
|
|
||||||
self.points.len()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macroquad::main("Graph")]
|
#[macroquad::main("Graph")]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
// Dot params
|
// Dot params
|
||||||
let realtive_y_origin =screen_height()*0.75;
|
let mut graph = Graph::new(Axis::One);
|
||||||
// FIXME realtive_x_origin doesn't work yet
|
|
||||||
let realtive_x_origin =0.;
|
|
||||||
let mut tail = Tail::new(Axis::One, realtive_y_origin);
|
|
||||||
|
|
||||||
// Selection box
|
|
||||||
let mut inital_x_pos = 0.;
|
|
||||||
let mut inital_y_pos = 0.;
|
|
||||||
|
|
||||||
// Tooling
|
// Tooling
|
||||||
let mut show_debug = true;
|
let mut show_debug = true;
|
||||||
|
let mut plot_delta_time = 0.;
|
||||||
|
|
||||||
// Serial
|
// Serial
|
||||||
|
let mut port = get_serial_port();
|
||||||
|
let mut serial_buf: Vec<u8> = vec![0; 8];
|
||||||
|
loop {
|
||||||
|
clear_background(BLACK);
|
||||||
|
|
||||||
|
graph.draw_axises();
|
||||||
|
|
||||||
|
let frame_delta_time = get_frame_time();
|
||||||
|
// keep track of the delta time since last plot
|
||||||
|
plot_delta_time += frame_delta_time;
|
||||||
|
|
||||||
|
if let Ok(x) = port.read(serial_buf.as_mut_slice()) {
|
||||||
|
let s: String = serial_buf.iter().take(x-1).map(|x| *x as char).collect();
|
||||||
|
if let Ok(parse) = s.parse::<f32>() {
|
||||||
|
// Only draw when requied
|
||||||
|
graph.place_next(plot_delta_time, 0., parse);
|
||||||
|
plot_delta_time = 0.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graph.draw();
|
||||||
|
|
||||||
|
if is_key_pressed(KeyCode::F3) {
|
||||||
|
show_debug = !show_debug;
|
||||||
|
}
|
||||||
|
// toggle debug box
|
||||||
|
if show_debug {
|
||||||
|
// Debug cursor information
|
||||||
|
let (mouse_x, mouse_y) = mouse_position();
|
||||||
|
let size = measure_text(&format!("x{mouse_x}, y{}",-(mouse_y-graph.y_origin)), None, 30,1.);
|
||||||
|
draw_rectangle(mouse_x, mouse_y+(size.offset_y/4.), size.width, -(size.height), WHITE);
|
||||||
|
draw_text(&format!("x{}, y{}", mouse_x+graph.x_origin,-(mouse_y-graph.y_origin)), mouse_x, mouse_y, 30., BLACK);
|
||||||
|
|
||||||
|
// Debug textbox
|
||||||
|
let mut debug = DebugWindow::new();
|
||||||
|
debug.add_line(format!("FPS {:04}, Frametime {:05.2}ms", get_fps(), frame_delta_time * 1000.0));
|
||||||
|
debug.add_line(format!("Tail Length {TAIL_LEN}, px/s {:.2}", graph.px_per_s));
|
||||||
|
debug.add_line(format!("Cursor Pos {:?}", mouse_position()));
|
||||||
|
debug.add_line(format!("Serial Port {}, Baud Rate {}", port.name().unwrap_or("Unknown".to_string()), port.baud_rate().map_or(String::from("N/A"), |f| f.to_string())));
|
||||||
|
debug.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
next_frame().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_serial_port() -> Box<dyn SerialPort> {
|
||||||
let port = serialport::available_ports()
|
let port = serialport::available_ports()
|
||||||
.expect("No ports found!")
|
.expect("No ports found!")
|
||||||
.iter()
|
.iter()
|
||||||
@@ -170,95 +228,7 @@ async fn main() {
|
|||||||
.open().expect("Failed to open port");
|
.open().expect("Failed to open port");
|
||||||
Some(x)
|
Some(x)
|
||||||
});
|
});
|
||||||
let mut port = port.expect("Failed to find valid serial port");
|
let port = port.expect("Failed to find valid serial port");
|
||||||
let mut serial_buf: Vec<u8> = vec![0; 8];
|
port
|
||||||
let mut plot_delta_time = 0.;
|
|
||||||
loop {
|
|
||||||
clear_background(BLACK);
|
|
||||||
match tail.axis {
|
|
||||||
Axis::One => {
|
|
||||||
draw_line(realtive_x_origin,realtive_y_origin,screen_width(),realtive_y_origin,1.,DARKGRAY);
|
|
||||||
},
|
|
||||||
Axis::Two => {
|
|
||||||
// horizontal (x)
|
|
||||||
draw_line(0.,realtive_y_origin,screen_width(),realtive_y_origin,1.,DARKGRAY);
|
|
||||||
// vertical (y)
|
|
||||||
draw_line(realtive_x_origin,realtive_y_origin, realtive_x_origin,screen_height(),1.,DARKGRAY);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
let frame_delta_time = get_frame_time();
|
|
||||||
let mut y_displacement = 0.;
|
|
||||||
let mut x_displacement = 0.;
|
|
||||||
// keep track of the delta time since last plot
|
|
||||||
plot_delta_time += frame_delta_time;
|
|
||||||
|
|
||||||
if let Ok(x) = port.read(serial_buf.as_mut_slice()) {
|
|
||||||
let s: String = serial_buf.iter().take(x-1).map(|x| *x as char).collect();
|
|
||||||
if let Ok(parse) = s.parse::<f32>() {
|
|
||||||
y_displacement = parse;
|
|
||||||
|
|
||||||
// only draw when requied
|
|
||||||
tail.place_next(plot_delta_time, x_displacement, -y_displacement);
|
|
||||||
plot_delta_time = 0.;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tail.draw();
|
|
||||||
|
|
||||||
// Info about the cursor locaiton
|
|
||||||
let (mouse_x, mouse_y) = mouse_position();
|
|
||||||
|
|
||||||
let size = measure_text(&format!("x{mouse_x}, y{}",-1.*(mouse_y-realtive_y_origin)), None, 30,1.);
|
|
||||||
draw_rectangle(mouse_x, mouse_y, size.width, -(size.height+5.), WHITE);
|
|
||||||
draw_text(&format!("x{}, y{}", mouse_x+realtive_x_origin,-1.*(mouse_y-realtive_y_origin)), mouse_x, mouse_y-5., 30., BLACK);
|
|
||||||
|
|
||||||
|
|
||||||
if is_key_down(KeyCode::S) {
|
|
||||||
if y_displacement < screen_height()/2. {
|
|
||||||
y_displacement += 10.;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_key_down(KeyCode::W) {
|
|
||||||
if y_displacement > -(screen_height()/2.) {
|
|
||||||
y_displacement -= 10.;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_key_down(KeyCode::D) {
|
|
||||||
if x_displacement < screen_width()/2. {
|
|
||||||
x_displacement += 10.;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_key_down(KeyCode::A) {
|
|
||||||
if x_displacement > -(screen_width()/2.) {
|
|
||||||
x_displacement -= 10.;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_key_pressed(KeyCode::F3) {
|
|
||||||
show_debug = !show_debug;
|
|
||||||
}
|
|
||||||
// selection box
|
|
||||||
if is_mouse_button_pressed(MouseButton::Left) {
|
|
||||||
(inital_x_pos, inital_y_pos) = mouse_position();
|
|
||||||
}
|
|
||||||
if is_mouse_button_down(MouseButton::Left) {
|
|
||||||
|
|
||||||
let (x, y) = mouse_position();
|
|
||||||
let width = x - inital_x_pos;
|
|
||||||
let height = y - inital_y_pos;
|
|
||||||
|
|
||||||
draw_rectangle(inital_x_pos, inital_y_pos, width, height, Color { r: 0.2, g: 0.1, b: 1., a: 0.3 });
|
|
||||||
}
|
|
||||||
// toggle debug box
|
|
||||||
if show_debug {
|
|
||||||
let mut debug = DebugWindow::new();
|
|
||||||
debug.add_line(format!("FPS {:03}, Latency {:.2}ms", get_fps(), frame_delta_time * 1000.0));
|
|
||||||
debug.add_line(format!("Tail Length {TAIL_LEN}, px/s {:.2}", tail.px_per_s));
|
|
||||||
debug.add_line(format!("Cursor Pos {:?}", mouse_position()));
|
|
||||||
debug.add_line(format!("Serial Port {}, Baud Rate {}", port.name().unwrap_or("Unknown".to_string()), port.baud_rate().unwrap_or(0)));
|
|
||||||
debug.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
next_frame().await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user