From 80c4c3604c5c9fd0156e72bcc543267fc99c3170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Neuh=C3=A4user?= Date: Sat, 26 Jul 2025 17:17:05 +0200 Subject: [PATCH] Support lines in all directions and add squares --- README.md | 3 ++- src/framebuffer.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++-- src/main.rs | 18 ++++--------- 3 files changed, 72 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 372bebc..325091c 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ NovaOS is a expository project where I build a kernel from scratch for a Raspber - UART ✓ - GPIOs ✓ - GPIO Interrupts ✓ -- Frame Buffer +- Communicate with peripherals via mailboxes ✓ +- Frame Buffer ✓ - MMU - Basic Terminal over UART diff --git a/src/framebuffer.rs b/src/framebuffer.rs index aa80896..939e3cf 100644 --- a/src/framebuffer.rs +++ b/src/framebuffer.rs @@ -103,7 +103,9 @@ impl FrameBuffer { } } - /*Bresenham's line algorithm */ + /*Bresenham's line algorithm + TODO: check if its possible to optimize y1==y2 case + */ pub fn draw_line(&self, x1: u32, y1: u32, x2: u32, y2: u32) { if x1 == x2 { for y in y1..=y2 { @@ -111,6 +113,44 @@ impl FrameBuffer { } return; } + + if (y2 as i32 - y1 as i32).abs() < (x2 as i32 - x1 as i32).abs() { + if x1 > x2 { + self.plot_line_low(x2, y2, x1, y1); + } else { + self.plot_line_low(x1, y1, x2, y2); + } + } else { + if y1 > y2 { + self.plot_line_high(x2, y2, x1, y1); + } else { + self.plot_line_high(x1, y1, x2, y2); + } + } + } + + pub fn draw_square(&self, x1: u32, y1: u32, x2: u32, y2: u32) { + self.draw_line(x1, y1, x2, y1); + self.draw_line(x1, y2, x2, y2); + self.draw_line(x1, y1, x1, y2); + self.draw_line(x2, y1, x2, y2); + } + + pub fn draw_square_fill(&self, x1: u32, y1: u32, x2: u32, y2: u32) { + let mut y_start = y1; + let mut y_end = y2; + + if y2 < y1 { + y_start = y2; + y_end = y1; + } + + for y in y_start..=y_end { + self.draw_line(x1, y, x2, y); + } + } + + fn plot_line_low(&self, x1: u32, y1: u32, x2: u32, y2: u32) { let dx = x2 as i32 - x1 as i32; let mut dy = y2 as i32 - y1 as i32; let mut yi = 1; @@ -126,13 +166,36 @@ impl FrameBuffer { for x in x1..=x2 { self.draw_pixel(x, y as u32); if d > 0 { - y = y + yi; + y += yi; d += 2 * (dy - dx); } else { d += 2 * dy; } } } + fn plot_line_high(&self, x1: u32, y1: u32, x2: u32, y2: u32) { + let mut dx = x2 as i32 - x1 as i32; + let dy = y2 as i32 - y1 as i32; + let mut xi: i32 = 1; + + let mut d = 2 * dy - dx; + let mut x = x1 as i32; + + if dx < 0 { + xi = -1; + dx = -dx; + } + + for y in y1..=y2 { + self.draw_pixel(x as u32, y); + if d > 0 { + x += xi; + d += 2 * (dx - dy); + } else { + d += 2 * dx; + } + } + } } pub fn print_display_resolution() { diff --git a/src/main.rs b/src/main.rs index c072687..591688f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -98,19 +98,11 @@ pub extern "C" fn kernel_main() -> ! { print_display_resolution(); fb.draw_line(10, 10, 1000, 10); - fb.draw_line(10, 10, 1000, 200); - fb.draw_line(10, 10, 1000, 300); - fb.draw_line(10, 10, 1000, 400); - fb.draw_line(10, 10, 1000, 500); - fb.draw_line(10, 10, 1000, 600); - fb.draw_line(10, 10, 1000, 700); - fb.draw_line(10, 10, 1000, 800); - fb.draw_line(10, 10, 1000, 900); - fb.draw_line(10, 10, 1000, 1000); - fb.draw_line(10, 10, 100, 1000); - - fb.draw_line(1800, 10, 1000, 900); - fb.draw_line(1800, 500, 1000, 100); + fb.draw_line(1000, 20, 10, 20); + fb.draw_square(500, 500, 600, 700); + fb.draw_square_fill(800, 800, 900, 900); + fb.draw_square_fill(1000, 800, 1200, 700); + fb.draw_square_fill(900, 100, 800, 150); loop { let temp = read_soc_temp();