2022-08-01 21:56:01 -05:00
|
|
|
use crate::{hardware::MOUSE, vga_e::VGAE};
|
2022-07-31 01:54:01 -05:00
|
|
|
use vga::{colors::Color16, writers::GraphicsWriter};
|
|
|
|
|
|
|
|
const TERM_MINUS_ONE_LINE: usize = 4720;
|
2022-08-02 01:52:03 -05:00
|
|
|
const CURSOR_COLOR: Color16 = Color16::Cyan;
|
2022-07-31 01:54:01 -05:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Term {
|
|
|
|
dirty: bool,
|
|
|
|
term: [char; 80 * 60],
|
2022-07-31 05:22:39 -05:00
|
|
|
x: u8,
|
2022-07-31 01:54:01 -05:00
|
|
|
}
|
|
|
|
impl Term {
|
|
|
|
pub fn new() -> Self {
|
2022-07-31 05:22:39 -05:00
|
|
|
let mode = VGAE.lock();
|
|
|
|
mode.set_mode();
|
|
|
|
drop(mode);
|
|
|
|
|
2022-07-31 01:54:01 -05:00
|
|
|
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() {
|
2022-07-31 05:22:39 -05:00
|
|
|
if self.x == 79 {
|
2022-07-31 01:54:01 -05:00
|
|
|
self.move_up();
|
2022-07-31 05:22:39 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
match c {
|
|
|
|
'\u{08}' => {
|
|
|
|
if self.x == 0 {
|
2022-07-31 05:27:27 -05:00
|
|
|
// trace!("IMPOSSIBLE BACKSPACE");
|
|
|
|
return;
|
2022-07-31 05:22:39 -05:00
|
|
|
}
|
2022-07-31 06:21:50 -05:00
|
|
|
trace!("BACKSPACE");
|
2022-07-31 05:27:27 -05:00
|
|
|
self.x -= 1;
|
|
|
|
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = '\0';
|
2022-07-31 05:22:39 -05:00
|
|
|
}
|
|
|
|
'\n' => {
|
|
|
|
self.move_up();
|
|
|
|
self.x = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
c => {
|
|
|
|
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = c;
|
|
|
|
self.x += 1;
|
|
|
|
}
|
2022-07-31 01:54:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn move_up(&mut self) {
|
|
|
|
self.term.rotate_left(80);
|
|
|
|
for x in 0..80 {
|
|
|
|
self.term[TERM_MINUS_ONE_LINE + x] = '\0';
|
|
|
|
}
|
2022-07-31 05:22:39 -05:00
|
|
|
self.x = 0;
|
2022-07-31 01:54:01 -05:00
|
|
|
}
|
2022-07-31 05:22:39 -05:00
|
|
|
// pub fn initialize(&self) {
|
|
|
|
// let mode = VGAE.lock();
|
|
|
|
// mode.set_mode();
|
|
|
|
// drop(mode);
|
|
|
|
// }
|
2022-07-31 01:54:01 -05:00
|
|
|
|
|
|
|
pub fn draw_term(&mut self) {
|
|
|
|
if self.is_dirty() {
|
|
|
|
trace!("Redrawing");
|
2022-08-02 01:52:03 -05:00
|
|
|
use Color16::*;
|
2022-07-31 01:54:01 -05:00
|
|
|
let mode = VGAE.lock();
|
2022-08-02 01:52:03 -05:00
|
|
|
mode.clear_screen(DarkGrey);
|
2022-07-31 01:54:01 -05:00
|
|
|
|
2022-08-01 21:56:01 -05:00
|
|
|
let mouse_coord = x86_64::instructions::interrupts::without_interrupts(|| {
|
|
|
|
let cursor = MOUSE.lock();
|
2022-07-31 01:54:01 -05:00
|
|
|
|
2022-08-01 21:56:01 -05:00
|
|
|
(cursor.get_x() as usize, cursor.get_y() as usize)
|
|
|
|
});
|
2022-07-31 01:54:01 -05:00
|
|
|
|
2022-08-01 21:56:01 -05:00
|
|
|
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,
|
|
|
|
);
|
2022-07-31 01:54:01 -05:00
|
|
|
|
|
|
|
let mut x = 0;
|
|
|
|
let mut y = 0;
|
|
|
|
|
|
|
|
for c in self.term {
|
2022-08-02 01:52:03 -05:00
|
|
|
mode.draw_character(x * 8, y * 8, c, White);
|
2022-07-31 01:54:01 -05:00
|
|
|
if x == 79 {
|
|
|
|
y += 1;
|
|
|
|
x = 0;
|
|
|
|
} else {
|
|
|
|
x += 1
|
|
|
|
}
|
|
|
|
}
|
2022-08-02 01:52:03 -05:00
|
|
|
|
2022-07-31 03:03:59 -05:00
|
|
|
self.set_dirty(false);
|
2022-07-31 01:54:01 -05:00
|
|
|
trace!("Finished drawing");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|