maybe work?
This commit is contained in:
		
							parent
							
								
									3b9ab3acae
								
							
						
					
					
						commit
						23db40c577
					
				
					 1 changed files with 105 additions and 18 deletions
				
			
		
							
								
								
									
										121
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										121
									
								
								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;
 | 
				
			||||||
| 
						 | 
					@ -260,6 +264,9 @@ impl Display {
 | 
				
			||||||
        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