very good and cool updates to BuiltinShell

This commit is contained in:
able 2022-08-02 04:14:01 -05:00
parent becc123d1f
commit 834287cdd6
8 changed files with 255 additions and 136 deletions

View file

@ -1,9 +1,9 @@
,-""""-. OS: AbleOS ,-""""-. OS: $BLUE$AbleOS$RESET$
,'\ _ _`. Host: ??? ,'\ _ _`. Host: ???
/ \)_)-)_)-\ Kernel: AKern-{}-v{} / \)_)-)_)-\ Kernel: AKern-{}-v{}
: : Uptime: {} : : Uptime: {}
\ / Packages: None \ / Packages: None
\ / Shell: RhaiShell \ / Shell: BuiltinShell
`. ,' Resolution: 640x480 `. ,' Resolution: 640x480
`. ,' Terminal: VGABuffer `. ,' Terminal: VGABuffer
`.,' CPU: {} `.,' CPU: {}

View file

@ -6,7 +6,7 @@ user_processes = ["shell"]
enabled = true enabled = true
level = "Trace" level = "Trace"
log_to_serial = true log_to_serial = true
filter = [] filter = ["ableos::vterm"]
[tests] [tests]

View file

@ -1,6 +1,6 @@
use core::panic::PanicInfo; use core::panic::PanicInfo;
use crate::{arch::gdt, rhai_shell::KEYBUFF, VgaBuffer, SCREEN_BUFFER}; use crate::{arch::gdt, println, rhai_shell::KEYBUFF};
use cpuio::outb; use cpuio::outb;
use pic8259::ChainedPics; use pic8259::ChainedPics;
use qrcode::QrCode; use qrcode::QrCode;
@ -213,18 +213,6 @@ pub fn reset_pit_for_cpu() {
set_pit_3(1000); set_pit_3(1000);
} }
pub fn bsod(src: BSODSource) -> ! { pub fn bsod(src: BSODSource) -> ! {
trace!("{src:?}");
let mut mode = SCREEN_BUFFER.lock();
mode.force_redraw();
/*
for y in 0..480 {
for x in 0..640 {
mode.set_pixel(x, y, 0x0000ff00);
}
}
*/
let mut x = 1; let mut x = 1;
let mut y = 0; let mut y = 0;
@ -241,20 +229,7 @@ pub fn bsod(src: BSODSource) -> ! {
src1 src1
); );
for current in st.chars() { println!("\n{}", st);
if current == '\n' || x == 40 {
y += 1;
x = 1;
} else {
mode.draw_char(
(x * 14).try_into().unwrap(),
(y * 22).try_into().unwrap(),
current,
0xffff0000,
);
}
x += 1;
}
let mut x = 1; let mut x = 1;
let mut y = 34; let mut y = 34;
@ -277,19 +252,7 @@ pub fn bsod(src: BSODSource) -> ! {
.module_dimensions(2, 1) .module_dimensions(2, 1)
.build(); .build();
for current in image.chars() { println!("{}", image);
if current == '\n' {
y += 1;
x = 0;
} else {
if current == '█' {
mode.draw_filled_rect(x * 6, y * 7, (x * 6) + 6, (y * 7) + 7, 0xffffff00);
}
}
x += 1;
}
mode.copy_to_buffer();
sloop(); sloop();
} }

View file

@ -1,16 +1,3 @@
use ab_glyph::{Font, FontRef, Glyph};
use shadeable::{
evaluate_shader,
pixel_format::{get_b, get_g, get_r, Rgba64},
};
use spin::Lazy;
use vga::{colors::Color16, writers::GraphicsWriter};
use crate::vga_e::VGAE;
pub static SCREEN_BUFFER: Lazy<spin::Mutex<ScreenBuffer>> =
Lazy::new(|| spin::Mutex::new(ScreenBuffer::new(640, 480)));
const FONT_SCALE: f32 = 1.6; const FONT_SCALE: f32 = 1.6;
const GLYPH_HEIGHT: f32 = 18.0; const GLYPH_HEIGHT: f32 = 18.0;
@ -134,76 +121,6 @@ impl ScreenBuffer {
vga.set_mode(); vga.set_mode();
vga.clear_screen(vga::colors::Color16::Black); vga.clear_screen(vga::colors::Color16::Black);
} }
/// Draw a glyph on the screen at the given position
///
/// # Arguments
/// * `x` - the x position of the glyph
/// * `y` - the y position of the glyph
/// * `glyph` - the glyph to draw
/// * `color` - the color of the glyph
pub fn draw_char(&mut self, mut x: u32, mut y: u32, character: char, color: Rgba64) {
// trace!["Judy Hopps is thicc af"];
// let mode = *VGAE.lock();
// trace!["She got them bouncy bunny buns"];
let basic_multingual_plane = FontRef::try_from_slice(include_bytes!(
"../../../ableos/assets/fonts/unifont-14.0.01.ttf"
))
.unwrap();
let supplementary_multilingual_plane = FontRef::try_from_slice(include_bytes!(
"../../../ableos/assets/fonts/unifont_upper-14.0.01.ttf"
))
.unwrap();
// let mut has_char = false;
// for x in font.codepoint_ids() {
// if x.1 == character {
// has_char = true;
// break;
// }
// }
let in_supp_plane = character as u32 > 0xffff;
let plane = match in_supp_plane {
false => basic_multingual_plane,
true => supplementary_multilingual_plane,
};
match character {
'\n' => {
// x = 0;
// y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
}
_ => {
let q_glyph: Glyph = plane.glyph_id(character).with_scale_and_position(
20.0 * FONT_SCALE,
ab_glyph::point(GLYPH_WIDTH * FONT_SCALE, GLYPH_HEIGHT * FONT_SCALE),
);
// elf: I don't know if GLYPH_HEIGHT is in the right units here. I'm just guessing.
if x as usize > self.size.x {
x = 0;
y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
}
if let Some(q) = plane.outline_glyph(q_glyph) {
q.draw(|gx, gy, c| {
if c > 0.0015 {
let corner = q.px_bounds().min;
self.set_pixel(
gx as usize + corner.x as usize + x as usize,
gy as usize + corner.y as usize + y as usize,
color,
);
}
});
}
}
}
}
} }
pub fn get_coordinates(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<(usize, usize)> { pub fn get_coordinates(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<(usize, usize)> {
@ -341,3 +258,74 @@ pub fn into_vga_16(rgba_64: Rgba64) -> Color16 {
(High, High, High) => White, (High, High, High) => White,
} }
} }
// TODO: Incorporate this into the ableos vga crate
/// Draw a glyph on the screen at the given position
///
/// # Arguments
/// * `x` - the x position of the glyph
/// * `y` - the y position of the glyph
/// * `glyph` - the glyph to draw
/// * `color` - the color of the glyph
pub fn draw_char(&mut self, mut x: u32, mut y: u32, character: char, color: Rgba64) {
// trace!["Judy Hopps is thicc af"];
// let mode = *VGAE.lock();
// trace!["She got them bouncy bunny buns"];
let basic_multingual_plane = FontRef::try_from_slice(include_bytes!(
"../../../ableos/assets/fonts/unifont-14.0.01.ttf"
))
.unwrap();
let supplementary_multilingual_plane = FontRef::try_from_slice(include_bytes!(
"../../../ableos/assets/fonts/unifont_upper-14.0.01.ttf"
))
.unwrap();
// let mut has_char = false;
// for x in font.codepoint_ids() {
// if x.1 == character {
// has_char = true;
// break;
// }
// }
let in_supp_plane = character as u32 > 0xffff;
let plane = match in_supp_plane {
false => basic_multingual_plane,
true => supplementary_multilingual_plane,
};
match character {
'\n' => {
// x = 0;
// y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
}
_ => {
let q_glyph: Glyph = plane.glyph_id(character).with_scale_and_position(
20.0 * FONT_SCALE,
ab_glyph::point(GLYPH_WIDTH * FONT_SCALE, GLYPH_HEIGHT * FONT_SCALE),
);
// elf: I don't know if GLYPH_HEIGHT is in the right units here. I'm just guessing.
if x as usize > self.size.x {
x = 0;
y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
}
if let Some(q) = plane.outline_glyph(q_glyph) {
q.draw(|gx, gy, c| {
if c > 0.0015 {
let corner = q.px_bounds().min;
self.set_pixel(
gx as usize + corner.x as usize + x as usize,
gy as usize + corner.y as usize + y as usize,
color,
);
}
});
}
}
}
}

View file

@ -47,7 +47,7 @@ pub mod devices;
pub mod driver_traits; pub mod driver_traits;
pub mod experiments; pub mod experiments;
pub mod filesystem; pub mod filesystem;
pub mod graphics; // pub mod graphics;
pub mod kernel_state; pub mod kernel_state;
pub mod keyboard; pub mod keyboard;
pub mod kmain; pub mod kmain;

View file

@ -42,7 +42,7 @@ impl core::fmt::Write for Stdout {
// x86_64::instructions::interrupts::without_interrupts(|| { // x86_64::instructions::interrupts::without_interrupts(|| {
let mut term = TERM.lock(); let mut term = TERM.lock();
term.set_dirty(true); term.set_dirty(true);
term.print(s.to_string()); term.print(s);
drop(term); drop(term);
// }); // });
// trace!("Finished printing"); // trace!("Finished printing");

View file

@ -117,7 +117,8 @@ pub fn real_shell() {
loop { loop {
match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) { match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) {
Some('\n') => { Some('\n') => {
println!(); // panic!();
// println!();
// match engine.eval_with_scope::<rhai::Dynamic>(&mut scope, &buf) { // match engine.eval_with_scope::<rhai::Dynamic>(&mut scope, &buf) {
// Ok(o) => println!("{o}"), // Ok(o) => println!("{o}"),
@ -177,6 +178,11 @@ pub fn command_parser(user: String, command: String) {
println!("{}", dir_entry.file_name_string()); println!("{}", dir_entry.file_name_string());
} }
} }
"echo" => {
echo_file(iter.next().unwrap().to_string(), fs);
}
"quit" => shutdown(), "quit" => shutdown(),
_ => { _ => {
@ -254,3 +260,27 @@ pub fn list_files_in_dir(
entry_list entry_list
} }
pub static CURRENT_DIR: Lazy<spin::Mutex<String>> = Lazy::new(|| spin::Mutex::new("/".to_string()));
pub fn echo_file(path: String, fs: &Synced<Ext2<Size1024, Vec<u8>>>) {
let mut current_dir = CURRENT_DIR.lock();
current_dir.push_str(&path);
let file = fs
.open(current_dir.as_bytes(), OpenOptions::new().read(true))
.unwrap();
if file.is_dir() {
// println!("{} is a directory", path);
} else {
let mut file_contents = Vec::new();
let _ret = file.read_to_end(&mut file_contents).unwrap();
let file_contents_str = String::from_utf8_lossy(&file_contents);
println!("{}", file_contents_str);
}
}

View file

@ -1,4 +1,5 @@
use crate::{hardware::MOUSE, vga_e::VGAE}; use crate::{hardware::MOUSE, vga_e::VGAE};
use logos::{Lexer, Logos};
use vga::{colors::Color16, writers::GraphicsWriter}; use vga::{colors::Color16, writers::GraphicsWriter};
const TERM_MINUS_ONE_LINE: usize = 4720; const TERM_MINUS_ONE_LINE: usize = 4720;
@ -7,7 +8,7 @@ const CURSOR_COLOR: Color16 = Color16::Cyan;
#[derive(Debug)] #[derive(Debug)]
pub struct Term { pub struct Term {
dirty: bool, dirty: bool,
term: [char; 80 * 60], term: [(char, Color16); 80 * 60],
x: u8, x: u8,
} }
impl Term { impl Term {
@ -19,7 +20,7 @@ impl Term {
Self { Self {
dirty: false, dirty: false,
x: 0, x: 0,
term: ['\0'; 80 * 60], term: [('\0', Color16::LightGrey); 80 * 60],
} }
} }
pub fn is_dirty(&self) -> bool { pub fn is_dirty(&self) -> bool {
@ -30,7 +31,7 @@ impl Term {
self.dirty = dirty self.dirty = dirty
} }
pub fn print(&mut self, data: String) { pub fn print(&mut self, data: &str) {
for c in data.chars() { for c in data.chars() {
if self.x == 79 { if self.x == 79 {
self.move_up(); self.move_up();
@ -45,7 +46,7 @@ impl Term {
} }
trace!("BACKSPACE"); trace!("BACKSPACE");
self.x -= 1; self.x -= 1;
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = '\0'; self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = ('\0', Color16::LightGrey);
} }
'\n' => { '\n' => {
self.move_up(); self.move_up();
@ -53,16 +54,81 @@ impl Term {
} }
c => { c => {
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = c; self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = (c, Color16::White);
self.x += 1; self.x += 1;
} }
} }
} }
} }
// TODO:DEADLOCK: Fix this up
pub fn cprint(&mut self, data: &str) {
let lex = Token::lexer(data);
trace!("{:?}", lex);
let mut color = Color16::Red;
for toke in lex {
match toke {
Token::Error =>
// unsafe { asm!("int 54") },
{}
Token::TBlack => color = Color16::Black,
Token::TBlue => {
color = Color16::Blue;
trace!("");
}
Token::TGreen => color = Color16::Green,
Token::TCyan => color = Color16::Cyan,
Token::TRed => color = Color16::Red,
Token::TMagenta => color = Color16::Magenta,
Token::TBrown => color = Color16::Brown,
Token::TLightGrey => color = Color16::LightGrey,
Token::TDarkGrey => color = Color16::DarkGrey,
Token::TLightBlue => color = Color16::LightBlue,
Token::TLightGreen => color = Color16::LightGreen,
Token::TLightCyan => color = Color16::LightCyan,
Token::TLightRed => color = Color16::LightRed,
Token::TPink => color = Color16::Pink,
Token::TYellow => color = Color16::Yellow,
Token::TWhite => color = Color16::White,
Token::Text(st) => {
for c in st.chars() {
if self.x == 79 {
self.move_up();
return;
}
match c {
'\u{08}' => {
if self.x == 0 {
// trace!("IMPOSSIBLE BACKSPACE");
return;
}
trace!("BACKSPACE");
self.x -= 1;
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] =
('\0', Color16::LightGrey);
}
'\n' => {
self.move_up();
self.x = 0;
}
c => {
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = (c, color);
self.x += 1;
}
}
}
}
}
}
}
pub fn move_up(&mut self) { pub fn move_up(&mut self) {
self.term.rotate_left(80); self.term.rotate_left(80);
for x in 0..80 { for x in 0..80 {
self.term[TERM_MINUS_ONE_LINE + x] = '\0'; self.term[TERM_MINUS_ONE_LINE + x] = ('\0', Color16::LightGrey);
} }
self.x = 0; self.x = 0;
} }
@ -105,7 +171,7 @@ impl Term {
let mut y = 0; let mut y = 0;
for c in self.term { for c in self.term {
mode.draw_character(x * 8, y * 8, c, White); mode.draw_character(x * 8, y * 8, c.0, c.1);
if x == 79 { if x == 79 {
y += 1; y += 1;
x = 0; x = 0;
@ -119,3 +185,75 @@ impl Term {
} }
} }
} }
#[derive(Logos, Debug, Clone, PartialEq)]
pub enum Token {
#[regex(r"[\t\n\f]+", logos::skip)]
#[error]
Error,
#[token("$BLACK$")]
TBlack,
#[token("$BLUE$")]
TBlue,
#[token("$GREEN$")]
TGreen,
#[token("$CYAN$")]
TCyan,
#[token("$RED$")]
TRed,
#[token("$MAGENTA$")]
TMagenta,
#[token("$BROWN$")]
TBrown,
#[token("$LIGHTGREY$")]
TLightGrey,
#[token("$DARKGREY$")]
TDarkGrey,
#[token("$LIGHTBLUE$")]
TLightBlue,
#[token("$LIGHTGREEN$")]
TLightGreen,
#[token("$LIGHTCYAN$")]
TLightCyan,
#[token("$LIGHTRED$")]
TLightRed,
#[token("$PINK$")]
TPink,
#[token("$YELLOW$")]
TYellow,
#[token("$WHITE$")]
TWhite,
#[regex("/[\x00-\x7F]/", text_lex)]
Text(String),
}
fn text_lex(lex: &mut Lexer<Token>) -> String {
lex.slice().into()
}
impl Into<Color16> for Token {
fn into(self) -> Color16 {
match self {
Token::Error => todo!(),
Token::TBlack => Color16::Black,
Token::TBlue => Color16::Blue,
Token::TGreen => Color16::Green,
Token::TCyan => Color16::Cyan,
Token::TRed => Color16::Red,
Token::TMagenta => Color16::Magenta,
Token::TBrown => Color16::Brown,
Token::TLightGrey => Color16::LightGrey,
Token::TDarkGrey => Color16::DarkGrey,
Token::TLightBlue => Color16::LightBlue,
Token::TLightGreen => Color16::LightGreen,
Token::TLightCyan => Color16::LightCyan,
Token::TLightRed => Color16::LightRed,
Token::TPink => Color16::Pink,
Token::TYellow => Color16::Yellow,
Token::TWhite => Color16::White,
Token::Text(_) => todo!(),
}
}
}