use core::panic; use limine::framebuffer::Framebuffer; use spin::{Mutex, Lazy}; use crate::{colour::Color, FRAMEBUFFER_REQUEST}; pub static FRAMEBUFFER_WRITER: Lazy>> = Lazy::new(|| Mutex::new( if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() { let framebuffer = framebuffer_response.framebuffers().next().unwrap(); Some(FramebufferWriter::new(framebuffer)) } else { panic!("Framebuffer request failed"); } )); pub struct FramebufferWriter<'a> { framebuffer: Framebuffer<'a>, } unsafe impl<'a> Send for FramebufferWriter<'a> {} unsafe impl<'a> Sync for FramebufferWriter<'a> {} impl<'a> FramebufferWriter<'a> { pub fn new(framebuffer: Framebuffer<'a>) -> Self { Self { framebuffer, } } pub fn write_pixel(&self, x: usize, y: usize, color: Color) { let pitch = self.framebuffer.pitch() as usize; let bpp = (self.framebuffer.bpp() / 8) as usize; let pixel_offset = y * pitch + x * bpp; unsafe { *(self.framebuffer.addr().add(pixel_offset) as *mut u32) = color.into(); } } pub fn render_frame(&self, buffer: &[Color; 1280 * 800]) { for (y, row) in buffer.chunks(1280).enumerate() { for (x, pixel) in row.iter().enumerate() { self.write_pixel(x, y, *pixel); } } } pub fn width(&self) -> u32 { self.framebuffer.width() as u32 } pub fn height(&self) -> u32 { self.framebuffer.height() as u32 } pub fn clear(&self) { let width = self.framebuffer.width() as usize; let height = self.framebuffer.height() as usize; for y in 0..height { for x in 0..width { self.write_pixel(x, y, Color::Black); } } } }