diff --git a/ableos/src/graphics/mod.rs b/ableos/src/graphics/mod.rs index d625edd5..38e193c0 100644 --- a/ableos/src/graphics/mod.rs +++ b/ableos/src/graphics/mod.rs @@ -1,195 +1,257 @@ use crate::vga_e::VGAE; +use ab_glyph::{Font, FontRef, Glyph}; use alloc::{boxed::Box, vec, vec::Vec}; -use shadeable::{ - evaluate_shader, - pixel_format::{Rgba64}, -}; +use shadeable::{evaluate_shader, pixel_format::Rgba64}; use spin; -use vga::{writers::GraphicsWriter}; +use vga::writers::GraphicsWriter; #[derive(Debug)] pub struct ScreenSize { - pub x: usize, - pub y: usize, + pub x: usize, + pub y: usize, } +const FONT_SCALE: f32 = 1.6; +const GLYPH_HEIGHT: f32 = 18.0; +const GLYPH_WIDTH: f32 = 10.0; + lazy_static::lazy_static! { pub static ref SCREEN_BUFFER: spin::Mutex = spin::Mutex::new(ScreenBuffer::new(640, 480)); } impl ScreenSize { - pub fn new(x: usize, y: usize) -> Self { - Self { x, y } - } + pub fn new(x: usize, y: usize) -> Self { + Self { x, y } + } } pub enum GraphicsReturn { - Ok, - ImproperScreenSize, + Ok, + ImproperScreenSize, } pub struct ScreenBuffer { - pub size: ScreenSize, - pub clear_color: Rgba64, - pub buff: Box<[Rgba64]>, // Vec, + pub size: ScreenSize, + pub clear_color: Rgba64, + pub buff: Box<[Rgba64]>, // Vec, } impl ScreenBuffer { - // Add optional size later - pub fn new(x: usize, y: usize) -> Self { - Self { - size: ScreenSize::new(x, y), - clear_color: 0, - buff: vec![0u64; x * y].into_boxed_slice(), - } - } - pub fn draw_filled_circle(&mut self, cx: i32, cy: i32, radius: usize, color: Rgba64) { - let r = radius as i32 * 2; - for y in 0..640 { - for x in 0..480 { - let dx = cx - x as i32 * 2 - 1; - let dy = cy - y as i32 * 2 - 1; + // Add optional size later + pub fn new(x: usize, y: usize) -> Self { + Self { + size: ScreenSize::new(x, y), + clear_color: 0, + buff: vec![0u64; x * y].into_boxed_slice(), + } + } + pub fn draw_filled_circle(&mut self, cx: i32, cy: i32, radius: usize, color: Rgba64) { + let r = radius as i32 * 2; + for y in 0..640 { + for x in 0..480 { + let dx = cx - x as i32 * 2 - 1; + let dy = cy - y as i32 * 2 - 1; - if dx * dx + dy * dy <= r * r { - self.set_pixel(x, y, color); - }; + if dx * dx + dy * dy <= r * r { + self.set_pixel(x, y, color); + }; + } + } + } + + #[inline] + pub fn set_pixel(&mut self, x: usize, y: usize, color: Rgba64) { + self.buff[y * self.size.x + x] = color; + } + + pub fn clear(&mut self) { + self.buff = vec![0u64; self.buff.len()].into_boxed_slice(); + } + + pub fn blit(&mut self, _width: usize, _height: usize) {} + pub fn draw_filled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) { + for y in y1..y2 { + for x in x1..x2 { + self.set_pixel(x, y, color); + } + } + } + pub fn draw_unfilled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) { + // x1 y1 => x2 y1 => x2 y2 => x1 y2 => x1 y1 + self.draw_line(x1, y1, x2, y1, color); + self.draw_line(x2, y1, x2, y2, color); + self.draw_line(x2, y2, x1, y2, color); + self.draw_line(x1, y2, x1, y1, color); + } + + #[inline] + pub fn draw_line(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) { + let x = crate::graphics::get_coordinates( + x1.try_into().unwrap(), + y1.try_into().unwrap(), + x2.try_into().unwrap(), + y2.try_into().unwrap(), + ); + + for coord in x { + self.set_pixel(coord.0, coord.1, color); + } + } + + pub fn shade(&mut self) { + for y in 0..100 { + for x in 0..100 { + let rgba_ret = evaluate_shader(x, y, self.buff[y * self.size.x + x]); + match rgba_ret { + Ok(pixel) => { + // info!("{:?}", pixel); + self.set_pixel(x, y, pixel); + } + + Err(err) => error!("{}", err), } - } - } + } + } - #[inline] - pub fn set_pixel(&mut self, x: usize, y: usize, color: Rgba64) { - self.buff[y * self.size.x + x] = color; - } + info!("Shaders done"); + } - pub fn clear(&mut self) { - self.buff = vec![0u64; self.buff.len()].into_boxed_slice(); - } + // TODO force clear + pub fn force_redraw(&mut self) { + use shadeable::pixel_format::into_vga_16; + VGAE.lock().clear_screen(into_vga_16(self.clear_color)); + } - pub fn blit(&mut self, _width: usize, _height: usize) {} - pub fn draw_filled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) { - for y in y1..y2 { - for x in x1..x2 { - self.set_pixel(x, y, color); + /// 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' => {} + _ => { + 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; } - } - } - pub fn draw_unfilled_rect( - &mut self, - x1: usize, - y1: usize, - x2: usize, - y2: usize, - color: Rgba64, - ) { - // x1 y1 => x2 y1 => x2 y2 => x1 y2 => x1 y1 - self.draw_line(x1, y1, x2, y1, color); - self.draw_line(x2, y1, x2, y2, color); - self.draw_line(x2, y2, x1, y2, color); - self.draw_line(x1, y2, x1, y1, color); - } - #[inline] - pub fn draw_line(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) { - let x = crate::graphics::get_coordinates( - x1.try_into().unwrap(), - y1.try_into().unwrap(), - x2.try_into().unwrap(), - y2.try_into().unwrap(), - ); - - for coord in x { - self.set_pixel(coord.0, coord.1, color); - } - } - - pub fn shade(&mut self) { - for y in 0..100 { - for x in 0..100 { - let rgba_ret = evaluate_shader(x, y, self.buff[y * self.size.x + x]); - match rgba_ret { - Ok(pixel) => { - // info!("{:?}", pixel); - self.set_pixel(x, y, pixel); - } - - Err(err) => error!("{}", err), - } + if let Some(q) = plane.outline_glyph(q_glyph) { + q.draw(|gx, gy, c| { + if c > 0.015 { + 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, + ); + } + }); } - } - - info!("Shaders done"); - } - - // TODO force clear - pub fn force_redraw(&mut self) { - use shadeable::pixel_format::into_vga_16; - VGAE.lock().clear_screen(into_vga_16(self.clear_color)); - } + } + } + } } pub trait VgaBuffer { - fn copy_to_buffer(&self) -> GraphicsReturn; + fn copy_to_buffer(&self) -> GraphicsReturn; } impl VgaBuffer for ScreenBuffer { - fn copy_to_buffer(&self) -> GraphicsReturn { - let mode = VGAE.lock(); - for y in 0..self.size.y { - for x in 0..self.size.x { - use shadeable::pixel_format::{into_vga_16}; - // let vga_color = get_color16(self.buff[y * self.size.x + x]); + fn copy_to_buffer(&self) -> GraphicsReturn { + let mode = VGAE.lock(); + for y in 0..self.size.y { + for x in 0..self.size.x { + use shadeable::pixel_format::into_vga_16; + // let vga_color = get_color16(self.buff[y * self.size.x + x]); - let vga_color = into_vga_16(self.buff[y * self.size.x + x]); + let vga_color = into_vga_16(self.buff[y * self.size.x + x]); - if into_vga_16(self.clear_color) != vga_color { - mode.set_pixel(x, y, vga_color); - } + if into_vga_16(self.clear_color) != vga_color { + mode.set_pixel(x, y, vga_color); } - } + } + } - GraphicsReturn::Ok - } + GraphicsReturn::Ok + } } pub fn get_coordinates(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<(usize, usize)> { - let mut coordinates: Vec<(usize, usize)> = vec![]; - let dx: i32 = i32::abs(x2 - x1); - let dy: i32 = i32::abs(y2 - y1); - let sx: i32 = { - if x1 < x2 { - 1 - } else { - -1 - } - }; - let sy: i32 = { - if y1 < y2 { - 1 - } else { - -1 - } - }; - let mut error: i32 = (if dx > dy { dx } else { -dy }) / 2; - let mut current_x: i32 = x1; - let mut current_y: i32 = y1; - loop { - coordinates.push((current_x as usize, current_y as usize)); - // info!("0 {:?}", (current_x, current_y)); + let mut coordinates: Vec<(usize, usize)> = vec![]; + let dx: i32 = i32::abs(x2 - x1); + let dy: i32 = i32::abs(y2 - y1); + let sx: i32 = { + if x1 < x2 { + 1 + } else { + -1 + } + }; + let sy: i32 = { + if y1 < y2 { + 1 + } else { + -1 + } + }; + let mut error: i32 = (if dx > dy { dx } else { -dy }) / 2; + let mut current_x: i32 = x1; + let mut current_y: i32 = y1; + loop { + coordinates.push((current_x as usize, current_y as usize)); + // info!("0 {:?}", (current_x, current_y)); - if current_x == x2 && current_y == y2 { - break; - } + if current_x == x2 && current_y == y2 { + break; + } - let error2: i32 = error; + let error2: i32 = error; - if error2 > -dx { - error -= dy; - current_x += sx; - } - if error2 < dy { - error += dx; - current_y += sy; - } - } - coordinates + if error2 > -dx { + error -= dy; + current_x += sx; + } + if error2 < dy { + error += dx; + current_y += sy; + } + } + coordinates } diff --git a/ableos/src/kmain.rs b/ableos/src/kmain.rs index dc6f3519..78d77772 100644 --- a/ableos/src/kmain.rs +++ b/ableos/src/kmain.rs @@ -3,135 +3,136 @@ use alloc::{format, vec::Vec}; use crate::{ - boot_conf::BootConfig, - capabilities::FileAccess, - file::{File, PathRep}, - scheduler::SCHEDULER, - ALIAS_TABLE, + boot_conf::BootConfig, + capabilities::FileAccess, + file::{File, PathRep}, + scheduler::SCHEDULER, + ALIAS_TABLE, }; // use crate::scheduler; use { - crate::{ - arch::{init, sloop}, - boot_conf, - experiments::{ - info::master, - systeminfo::{KERNEL_VERSION, RELEASE_TYPE}, - }, - graphics::{VgaBuffer, SCREEN_BUFFER}, - relib::network::socket::Socket, - relib::network::socket::{SimpleSock, SocketReturns}, - vga_e::{self, num_to_vga16}, - }, - alloc::{ - string::{String, ToString}, - vec, - }, - core::sync::atomic::{AtomicU64, Ordering::*}, - lazy_static::lazy_static, - log::*, - picorand::PicoRandGenerate, - rkyv::{ser::serializers::AllocSerializer, Deserialize}, - shadeable::pixel_format::from_vga_16, - y_compositor_protocol::Version, + crate::{ + arch::{init, sloop}, + boot_conf, + experiments::{ + info::master, + systeminfo::{KERNEL_VERSION, RELEASE_TYPE}, + }, + graphics::{VgaBuffer, SCREEN_BUFFER}, + relib::network::socket::Socket, + relib::network::socket::{SimpleSock, SocketReturns}, + vga_e::{self, num_to_vga16}, + }, + alloc::{ + string::{String, ToString}, + vec, + }, + core::sync::atomic::{AtomicU64, Ordering::*}, + lazy_static::lazy_static, + log::*, + picorand::PicoRandGenerate, + rkyv::{ser::serializers::AllocSerializer, Deserialize}, + shadeable::pixel_format::from_vga_16, + y_compositor_protocol::Version, }; #[no_mangle] #[allow(unconditional_recursion)] pub extern "C" fn stack_overflow() -> u8 { - stack_overflow(); - // meme number - 69 // NOTE: Any specific reason for this number aside from memes? + stack_overflow(); + // meme number + 69 // NOTE: Any specific reason for this number aside from memes? } lazy_static! { - pub static ref KEY_BUFFER: spin::Mutex = spin::Mutex::new("".to_string()); - pub static ref TICK: AtomicU64 = AtomicU64::new(0); - pub static ref BOOT_CONF: BootConfig = boot_conf::BootConfig::new(); + pub static ref KEY_BUFFER: spin::Mutex = spin::Mutex::new("".to_string()); + pub static ref TICK: AtomicU64 = AtomicU64::new(0); + pub static ref BOOT_CONF: BootConfig = boot_conf::BootConfig::new(); } /// The main entry point of the kernel #[no_mangle] pub fn kernel_main() -> ! { - init::init(); - log::set_max_level(BOOT_CONF.log_level()); + init::init(); + log::set_max_level(BOOT_CONF.log_level()); - use crate::scheduler::Priority; - let mut scheduler = SCHEDULER.lock(); + use crate::scheduler::Priority; + let mut scheduler = SCHEDULER.lock(); - use Priority::*; + use Priority::*; - let mut process_1 = scheduler.new_process(High); - process_1.capabilities.files = FileAccess::Some(vec![PathRep { - location: FileLocations::Home, - file_name: "test".to_string(), - }]); - scheduler.add_process(process_1); - for ref_process in &scheduler.list { - trace!("{:?}", ref_process); - } - drop(scheduler); + let mut process_1 = scheduler.new_process(High); + process_1.capabilities.files = FileAccess::Some(vec![PathRep { + location: FileLocations::Home, + file_name: "test".to_string(), + }]); + scheduler.add_process(process_1); + for ref_process in &scheduler.list { + trace!("{:?}", ref_process); + } + drop(scheduler); - use crate::proto_filetable::contain::FILE_TABLE; - use crate::proto_filetable::file::FileLocations; + use crate::proto_filetable::contain::FILE_TABLE; + use crate::proto_filetable::file::FileLocations; - let mut file_table = FILE_TABLE.lock(); - let mut new_file = File::new(FileLocations::Bin, "test".to_string(), "txt".to_string()); + let mut file_table = FILE_TABLE.lock(); + let mut new_file = File::new(FileLocations::Bin, "test".to_string(), "txt".to_string()); - new_file.write_bytes(b"Hello, world!"); - file_table.add_file("test", new_file); + new_file.write_bytes(b"Hello, world!"); + file_table.add_file("test", new_file); - let file = file_table.get_file("test"); + let file = file_table.get_file("test"); - match file { - Some(file) => { - let file_bytes = &file.data_pointer; - let file_string = String::from_utf8(file_bytes.to_vec()).unwrap(); - info!("{}", file_string); - } - None => { - info!("File not found"); - } - } + match file { + Some(file) => { + let file_bytes = &file.data_pointer; + let file_string = String::from_utf8(file_bytes.to_vec()).unwrap(); + info!("{}", file_string); + } + None => { + info!("File not found"); + } + } - crate::tests::screen_writer_test(); + crate::tests::screen_writer_test(); - use crate::wasm::WasmProgram; - let ret = WasmProgram::new_from_bytes(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]); - trace!("Binary Valid: {:?}", ret.validate_header()); + use crate::wasm::WasmProgram; + let ret = WasmProgram::new_from_bytes(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]); + trace!("Binary Valid: {:?}", ret.validate_header()); - sloop() + sloop() } /// called by arch specific timers to tick up all kernel related functions pub fn tick() { - let mut data = TICK.load(Relaxed); - data += 1; + let mut data = TICK.load(Relaxed); + data += 1; - crate::kernel_state::KERNEL_STATE.lock().update_state(); + crate::kernel_state::KERNEL_STATE.lock().update_state(); - let mut scheduler = SCHEDULER.lock(); - scheduler.bump_exec(); + // let mut scheduler = SCHEDULER.lock(); + // scheduler.bump_exec(); - TICK.store(data, Relaxed) + TICK.store(data, Relaxed) } + /// called every time a key is pressed to add it to the randomness pool pub fn key_entropy(key: u8) {} pub fn cpu_socket_startup() { - let mut cpu_info_socket = SimpleSock::new(); - cpu_info_socket.register_protocol("CPU_INFO".to_string()); + let mut cpu_info_socket = SimpleSock::new(); + cpu_info_socket.register_protocol("CPU_INFO".to_string()); - let x = master().unwrap(); - let _xyz = x.brand_string().unwrap(); + let x = master().unwrap(); + let _xyz = x.brand_string().unwrap(); } pub fn log_version_data() { - info!("{} v{}", RELEASE_TYPE, KERNEL_VERSION); - info!( - "Brand String: {:?}", - master().unwrap().brand_string().unwrap() - ); + info!("{} v{}", RELEASE_TYPE, KERNEL_VERSION); + info!( + "Brand String: {:?}", + master().unwrap().brand_string().unwrap() + ); } diff --git a/ableos/src/tests.rs b/ableos/src/tests.rs index c26d0b1a..80b7ec75 100644 --- a/ableos/src/tests.rs +++ b/ableos/src/tests.rs @@ -93,9 +93,11 @@ pub fn screen_writer_test() { // sock_print_id.write(format!("I look forward to ur ai stuff :^>").into()); // sock_print_id.write(format!("1....2....3....4....5....6....7....8....9").into()); + let mut mode = SCREEN_BUFFER.lock(); for current in (*String::from_utf8_lossy(&sock_print_id.peek().unwrap())).chars() { - vga_e::draw_char(0, 0, current, from_vga_16(Color16::Red)); + mode.draw_char(0, 0, current, from_vga_16(Color16::Red)); } + mode.copy_to_buffer(); } pub fn vga_boot_screen() { diff --git a/ableos/src/vga_e.rs b/ableos/src/vga_e.rs index 9aa76fa0..fb21b8ac 100644 --- a/ableos/src/vga_e.rs +++ b/ableos/src/vga_e.rs @@ -20,77 +20,6 @@ lazy_static::lazy_static! { pub static ref VGAE_BUFF_OFFSET_Y: spin::Mutex = spin::Mutex::new(0); } -const FONT_SCALE: f32 = 1.6; -const GLYPH_HEIGHT: f32 = 18.0; -const GLYPH_WIDTH: f32 = 10.0; - -/// 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 x: u32, mut y: u32, character: char, color: Rgba64) { - // trace!["Judy Hopps is thicc af"]; - // let mode = *VGAE.lock(); - let mut mode = SCREEN_BUFFER.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 is_in_basic_multilingual_plane = character as u32 <= 0xffff; - - let plane = match is_in_basic_multilingual_plane { - true => basic_multingual_plane, - false => supplementary_multilingual_plane, - }; - - match character { - '\n' => {} - _ => { - 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 > mode.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.015 { - let corner = q.px_bounds().min; - mode.set_pixel( - gx as usize + corner.x as usize + x as usize, - gy as usize + corner.y as usize + y as usize, - color, - ); - } - }); - } - } - } -} /// Converts a number to ... i forgor 💀 pub fn num_to_vga16(num: u8) -> Color16 {