bitsy_lang/sim/ext/
video.rs1use super::*;
2
3#[derive(Debug)]
4pub struct Video {
5 signal: u8,
6 hsync: bool,
7 vsync: bool,
8 frame_buffer: String,
9 disabled: bool,
10 initialized: bool,
11}
12
13impl Video {
14 pub fn new() -> Video {
15 Video {
16 signal: 0,
17 hsync: false,
18 vsync: false,
19 frame_buffer: String::new(),
20 disabled: false,
21 initialized: false,
22 }
23 }
24
25 pub fn disable(&mut self) {
26 self.disabled = true;
27 }
28}
29
30impl ExtInstance for Video {
31 fn incoming_ports(&self) -> Vec<PortName> { vec!["signal".to_string(), "hsync".to_string(), "vsync".to_string()] }
32
33 fn update(&mut self, portname: &PortName, value: value::Value) -> Vec<(PortName, value::Value)> {
34 if value.is_x() {
35 return vec![];
36 }
37 if portname == "signal" {
38 self.signal = value.try_into().unwrap();
39 } else if portname == "hsync" {
40 self.hsync = value.try_into().unwrap();
41 } else if portname == "vsync" {
42 self.vsync = value.try_into().unwrap();
43 }
44 vec![]
45 }
46
47 fn clock(&mut self) -> Vec<(PortName, Value)> {
48 if !self.disabled {
49 use std::fmt::Write;
50 let c: char = " ░▒▓".chars().collect::<Vec<char>>()[self.signal as usize];
51
52 write!(self.frame_buffer, "{c}{c}").unwrap();
53 if self.hsync {
54 writeln!(self.frame_buffer).unwrap();
55 }
56
57 if self.vsync {
58 std::thread::sleep(std::time::Duration::from_millis(30));
59
60 print!("\x1B[2J");
62
63 print!("\x1B[H");
65
66 println!("{}", self.frame_buffer);
67 self.frame_buffer.clear();
68 }
69 }
70 vec![]
71 }
72
73 fn reset(&mut self) -> Vec<(PortName, Value)>{
74 if !self.disabled {
75 if !self.initialized {
76 ctrlc::set_handler(move || {
77 println!("\x1B[?25h");
79 std::process::exit(0);
80 }).unwrap();
81 }
82
83 print!("\x1B[?25l");
85
86 print!("\x1B[2J");
88 }
89
90 self.initialized = true;
91
92 vec![]
93 }
94}