use super::*;
#[derive(Debug)]
pub struct Video {
name: String,
signal: u8,
hsync: bool,
vsync: bool,
frame_buffer: String,
disabled: bool,
initialized: bool,
}
impl Video {
pub fn new(name: String) -> Video {
Video {
name,
signal: 0,
hsync: false,
vsync: false,
frame_buffer: String::new(),
disabled: false,
initialized: false,
}
}
pub fn disable(&mut self) {
self.disabled = true;
}
}
impl Ext for Video {
fn name(&self) -> String { self.name.clone() }
fn instantiate(&mut self, _path: Path) {}
fn incoming_ports(&self) -> Vec<PortName> { vec!["signal".to_string(), "hsync".to_string(), "vsync".to_string()] }
fn update(&mut self, _path: Path, portname: &PortName, value: Value) -> Vec<(PortName, Value)> {
if value.is_x() {
return vec![];
}
if portname == "signal" {
self.signal = value.try_into().unwrap();
} else if portname == "hsync" {
self.hsync = value.try_into().unwrap();
} else if portname == "vsync" {
self.vsync = value.try_into().unwrap();
}
vec![]
}
fn clock(&mut self, _path: Path) -> Vec<(PortName, Value)> {
if !self.disabled {
use std::fmt::Write;
let c: char = " ░▒▓".chars().collect::<Vec<char>>()[self.signal as usize];
write!(self.frame_buffer, "{c}{c}").unwrap();
if self.hsync {
writeln!(self.frame_buffer).unwrap();
}
if self.vsync {
std::thread::sleep(std::time::Duration::from_millis(30));
print!("\x1B[2J");
print!("\x1B[H");
println!("{}", self.frame_buffer);
self.frame_buffer.clear();
}
}
vec![]
}
fn reset(&mut self, _path: Path) -> Vec<(PortName, Value)>{
if !self.disabled {
if !self.initialized {
ctrlc::set_handler(move || {
println!("\x1B[?25h");
std::process::exit(0);
}).unwrap();
}
print!("\x1B[?25l");
print!("\x1B[2J");
}
self.initialized = true;
vec![]
}
}