maybe work?
This commit is contained in:
parent
3b9ab3acae
commit
23db40c577
1 changed files with 105 additions and 18 deletions
123
src/main.rs
123
src/main.rs
|
@ -2,6 +2,8 @@ use std::fs::File;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::net::{ToSocketAddrs, UdpSocket};
|
use std::net::{ToSocketAddrs, UdpSocket};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use std::thread;
|
||||||
|
use std::sync::{Mutex,Arc};
|
||||||
mod color;
|
mod color;
|
||||||
// Constants from the C code
|
// Constants from the C code
|
||||||
const QUEUE_LEN: usize = 1000;
|
const QUEUE_LEN: usize = 1000;
|
||||||
|
@ -91,7 +93,7 @@ impl BouncingImage {
|
||||||
let index = (sy * self.img.width + sx) as usize * 4;
|
let index = (sy * self.img.width + sx) as usize * 4;
|
||||||
let rgba = &self.img.pixels[index..index + 4];
|
let rgba = &self.img.pixels[index..index + 4];
|
||||||
if rgba[3] > 0 { // Check alpha channel
|
if rgba[3] > 0 { // Check alpha channel
|
||||||
display.set_pixel((x + sx as i32) as u16, (y + sy as i32) as u16, rgba[0], rgba[1], rgba[2]);
|
//display.set_pixel((x + sx as i32) as u16, (y + sy as i32) as u16, rgba[0], rgba[1], rgba[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,12 +122,12 @@ impl Drawable for BouncingImage {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Circle {
|
struct Circle {
|
||||||
x: u32,
|
x: Arc<Mutex<u32>>,
|
||||||
y: u32,
|
y: Arc<Mutex<u32>>,
|
||||||
}
|
}
|
||||||
impl Circle {
|
impl Circle {
|
||||||
|
|
||||||
fn new(x:u32, y: u32) -> Self {
|
fn new(x:Arc<Mutex<u32>>, y: Arc<Mutex<u32>>) -> Self {
|
||||||
Circle {
|
Circle {
|
||||||
x,
|
x,
|
||||||
y
|
y
|
||||||
|
@ -133,7 +135,7 @@ impl Circle {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This exploits the eight-way symmetry of a circle.
|
/// This exploits the eight-way symmetry of a circle.
|
||||||
fn draw_circle_octants(&mut self, display: &mut Display, cx: u16, cy: u16, x: u16, y: u16, r: u8, g: u8, b: u8) {
|
fn draw_circle_octants(&mut self, display: &mut Display, cx: i32, cy: i32, x: i32, y: i32, r: u8, g: u8, b: u8) {
|
||||||
display.set_pixel(cx + x, cy + y, r, g, b);
|
display.set_pixel(cx + x, cy + y, r, g, b);
|
||||||
display.set_pixel(cx - x, cy + y, r, g, b);
|
display.set_pixel(cx - x, cy + y, r, g, b);
|
||||||
display.set_pixel(cx + x, cy - y, r, g, b);
|
display.set_pixel(cx + x, cy - y, r, g, b);
|
||||||
|
@ -164,7 +166,7 @@ impl Circle {
|
||||||
|
|
||||||
// Iterate through the first octant and draw points in all 8 octants
|
// Iterate through the first octant and draw points in all 8 octants
|
||||||
while y >= x {
|
while y >= x {
|
||||||
self.draw_circle_octants(display,center_x.try_into().unwrap(), center_y.try_into().unwrap(), x.try_into().unwrap(), y.try_into().unwrap(), r, g, b);
|
self.draw_circle_octants(display,center_x.try_into().unwrap(), center_y.try_into().unwrap(), x, y, r, g, b);
|
||||||
|
|
||||||
x += 1;
|
x += 1;
|
||||||
|
|
||||||
|
@ -193,9 +195,10 @@ impl Drawable for Circle {
|
||||||
v: 1.0,
|
v: 1.0,
|
||||||
};
|
};
|
||||||
let rgb: color::Rgb = hsv_color.into();
|
let rgb: color::Rgb = hsv_color.into();
|
||||||
|
let draw_y =*self.x.lock().unwrap();
|
||||||
let radius = (tick/30) % (1080/2);
|
let draw_x = *self.y.lock().unwrap();
|
||||||
self.draw_circle(display,self.x,self.y,radius.try_into().unwrap(),rgb.r,rgb.g,rgb.b);
|
let radius = (tick/30) % (1080/2);
|
||||||
|
self.draw_circle(display,draw_y,draw_x,radius.try_into().unwrap(),rgb.r,rgb.g,rgb.b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,13 +248,14 @@ impl Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a pixel color at a specific coordinate.
|
/// Sets a pixel color at a specific coordinate.
|
||||||
fn set_pixel(&mut self, x: u16, y: u16, r: u8, g: u8, b: u8) {
|
fn set_pixel(&mut self, x: i32, y: i32, r: u8, g: u8, b: u8) {
|
||||||
let offset = 2 + self.pos_in_buf * 7;
|
if let (Ok(output_x),Ok(output_y)) = (u16::try_from(x), u16::try_from(y)) {
|
||||||
|
let offset = 2 + self.pos_in_buf * 7;
|
||||||
let buf = &mut self.bufs[self.next_buf][offset..offset + 7];
|
let buf = &mut self.bufs[self.next_buf][offset..offset + 7];
|
||||||
buf[0] = x as u8;
|
buf[0] = output_x as u8;
|
||||||
buf[1] = (x >> 8) as u8;
|
buf[1] = (output_x >> 8) as u8;
|
||||||
buf[2] = y as u8;
|
buf[2] = output_y as u8;
|
||||||
buf[3] = (y >> 8) as u8;
|
buf[3] = (output_y >> 8) as u8;
|
||||||
buf[4] = r;
|
buf[4] = r;
|
||||||
buf[5] = g;
|
buf[5] = g;
|
||||||
buf[6] = b;
|
buf[6] = b;
|
||||||
|
@ -259,7 +263,10 @@ impl Display {
|
||||||
self.pos_in_buf += 1;
|
self.pos_in_buf += 1;
|
||||||
if self.pos_in_buf == 211 {
|
if self.pos_in_buf == 211 {
|
||||||
self.flush_frame();
|
self.flush_frame();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,25 +275,105 @@ impl Display {
|
||||||
fn blank_screen(&mut self) {
|
fn blank_screen(&mut self) {
|
||||||
for x in 0..DISPLAY_WIDTH {
|
for x in 0..DISPLAY_WIDTH {
|
||||||
for y in 0..DISPLAY_HEIGHT {
|
for y in 0..DISPLAY_HEIGHT {
|
||||||
self.set_pixel(x as u16, y as u16, 0, 0, 0);
|
//self.set_pixel(x as u16, y as u16, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.flush_frame();
|
self.flush_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Unpacks a 4-byte slice into two u16 values (little-endian).
|
||||||
|
fn unpack_coordinates(buffer: &[u8]) -> Option<(u16, u16)> {
|
||||||
|
if buffer.len() != 4 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// Try to convert the first 2 bytes to a u16 for x.
|
||||||
|
let x_bytes: [u8; 2] = buffer[0..2].try_into().ok()?;
|
||||||
|
// Try to convert the next 2 bytes to a u16 for y.
|
||||||
|
let y_bytes: [u8; 2] = buffer[2..4].try_into().ok()?;
|
||||||
|
|
||||||
|
// Reconstruct the u16 values from their little-endian byte representation.
|
||||||
|
let x = u16::from_le_bytes(x_bytes);
|
||||||
|
let y = u16::from_le_bytes(y_bytes);
|
||||||
|
|
||||||
|
Some((x, y))
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
|
|
||||||
|
let x:Arc<Mutex<u32>> = Arc::new(Mutex::new(0));
|
||||||
|
let x_thread = x.clone();
|
||||||
|
|
||||||
|
let y:Arc<Mutex<u32>>= Arc::new(Mutex::new(0));
|
||||||
|
let y_thread = y.clone();
|
||||||
|
|
||||||
|
let circle = Box::new(Circle::new(x,y));
|
||||||
let mut images:Vec<Box<dyn Drawable>> = vec![
|
let mut images:Vec<Box<dyn Drawable>> = vec![
|
||||||
// Box::new(BouncingImage::new("images/unicorn_cc.png", 13, -10, 1, -1, -1)),
|
// Box::new(BouncingImage::new("images/unicorn_cc.png", 13, -10, 1, -1, -1)),
|
||||||
// Box::new(BouncingImage::new("images/windows_logo.png", -8, 3, 2, -1, -1)),
|
// Box::new(BouncingImage::new("images/windows_logo.png", -8, 3, 2, -1, -1)),
|
||||||
// Box::new(BouncingImage::new("images/spade.png", 32, -12, 1, 0, 0)),
|
// Box::new(BouncingImage::new("images/spade.png", 32, -12, 1, 0, 0)),
|
||||||
// Box::new(BouncingImage::new("images/dvdvideo.png", 20, 6, 5, 1000, 800)),
|
// Box::new(BouncingImage::new("images/dvdvideo.png", 20, 6, 5, 1000, 800)),
|
||||||
// Box::new(BouncingImage::new("images/hackaday.png", 40, 18, 3, 500, 800)),
|
// Box::new(BouncingImage::new("images/hackaday.png", 40, 18, 3, 500, 800)),
|
||||||
Box::new(Circle::new(1920/2,1080/2))
|
circle
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut display = Display::new(DISPLAY_HOST, DISPLAY_PORT);
|
let mut display = Display::new(DISPLAY_HOST, DISPLAY_PORT);
|
||||||
let mut frame_counter: u32 = 0;
|
let mut frame_counter: u32 = 0;
|
||||||
|
thread::spawn(move || {
|
||||||
|
let bind_address = format!("0.0.0.0:12345");
|
||||||
|
|
||||||
|
// Bind the UDP socket to the specified address and port.
|
||||||
|
let socket = match UdpSocket::bind(&bind_address) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error: Could not bind to address {}: {}", bind_address, e);
|
||||||
|
panic!("aaaa");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Listening for UDP packets on {}", bind_address);
|
||||||
|
|
||||||
|
// Create a buffer to hold incoming data. 4 bytes for two u16 values.
|
||||||
|
let mut buf = [0u8; 4];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// Wait for a packet to arrive.
|
||||||
|
match socket.recv_from(&mut buf) {
|
||||||
|
Ok((number_of_bytes, src_addr)) => {
|
||||||
|
println!("\nReceived {} bytes from {}", number_of_bytes, src_addr);
|
||||||
|
|
||||||
|
// Ensure we received the correct number of bytes.
|
||||||
|
if number_of_bytes == 4 {
|
||||||
|
// Unpack the buffer into coordinates.
|
||||||
|
if let Some((x_rev, y_rev)) = unpack_coordinates(&buf) {
|
||||||
|
let x_32:u32 = x_rev.into();
|
||||||
|
let y_32:u32 = y_rev.into();
|
||||||
|
*x_thread.lock().unwrap() = x_32;
|
||||||
|
*y_thread.lock().unwrap() = y_32;
|
||||||
|
println!("Received Coordinates: X = {}, Y = {}", x_rev, y_rev);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// This case should ideally not be reached if number_of_bytes is 4.
|
||||||
|
eprintln!("Error: Failed to unpack coordinate data.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!(
|
||||||
|
"Warning: Received packet with incorrect size ({} bytes). Expected 4.",
|
||||||
|
number_of_bytes
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error receiving data: {}", e);
|
||||||
|
// Decide if you want to break the loop on an error.
|
||||||
|
// For a continuous server, you might just log and continue.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// display.blank_screen();
|
// display.blank_screen();
|
||||||
let mut tick:u32 = 0;
|
let mut tick:u32 = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue