use vga::{colors::Color16, writers::GraphicsWriter}; use crate::{ hardware::{MOUSE, _MOUSE}, vga_e::VGAE, }; const TERM_MINUS_ONE_LINE: usize = 4720; const CURSOR_COLOR: Color16 = Color16::Cyan; #[derive(Debug)] pub struct Term { dirty: bool, term: [char; 80 * 60], x: usize, } impl Term { pub fn new() -> Self { Self { dirty: false, x: 0, term: ['\0'; 80 * 60], } } pub fn is_dirty(&self) -> bool { self.dirty } pub fn set_dirty(&mut self, dirty: bool) { self.dirty = dirty } pub fn print(&mut self, data: String) { for c in data.chars() { if self.x == 79 || c == '\n' { self.move_up(); self.x = 0; } else { self.term[TERM_MINUS_ONE_LINE + self.x] = c; self.x += 1; } } } pub fn move_up(&mut self) { self.term.rotate_left(80); for x in 0..80 { self.term[TERM_MINUS_ONE_LINE + x] = '\0'; } } pub fn initialize(&self) { let mode = VGAE.lock(); mode.set_mode(); drop(mode); } pub fn draw_term(&mut self) { if self.is_dirty() { trace!("Redrawing"); let mode = VGAE.lock(); mode.clear_screen(Color16::Black); let mouse_coord = x86_64::instructions::interrupts::without_interrupts(|| { let cursor = MOUSE.lock(); (cursor.get_x() as usize, cursor.get_y() as usize) }); mode.draw_line( (mouse_coord.0 as isize + 0, mouse_coord.1 as isize + 0), (mouse_coord.0 as isize + 10, mouse_coord.1 as isize + 10), CURSOR_COLOR, ); mode.draw_line( (mouse_coord.0 as isize + 0, mouse_coord.1 as isize + 0), (mouse_coord.0 as isize + 5, mouse_coord.1 as isize + 0), CURSOR_COLOR, ); mode.draw_line( (mouse_coord.0 as isize + 0, mouse_coord.1 as isize + 0), (mouse_coord.0 as isize + 0, mouse_coord.1 as isize + 5), CURSOR_COLOR, ); let mut x = 0; let mut y = 0; for c in self.term { mode.draw_character(x * 8, y * 8, c, Color16::White); if x == 79 { y += 1; x = 0; } else { x += 1 } } self.set_dirty(false); trace!("Finished drawing"); } } }