diff --git a/src/drawing/device.rs b/src/drawing/device.rs index ebde02d..b568310 100644 --- a/src/drawing/device.rs +++ b/src/drawing/device.rs @@ -2,18 +2,32 @@ use super::Point; use crate::writers::{GraphicsWriter, Screen}; use core::cmp::{max, min}; +/// A helper trait used to draw to the vga screen in graphics mode. pub trait Device where Self: Screen + GraphicsWriter, Color: Clone + Copy, { - /// Draws a character at the given `(x, y)` coordinant to the specified `color`. + /// Draws an 8x8 character at the given `(x, y)` coordinant to the specified `color`. + /// + /// **Note:** This does no bounds checking and will panick if + /// any of the pixels fall outside of the screen range. + /// `x + 8 >= self.get_width() || y + 8 >= self.get_height()`. fn draw_character(&mut self, x: usize, y: usize, character: char, color: Color); /// Draws a line from `start` to `end` with the specified `color`. + /// + /// **Note:** This does no bounds checking and will panick if + /// `x >= self.get_width() || y >= self.get_height()`. fn draw_line(&mut self, start: Point, end: Point, color: Color); - fn draw_triangle(&mut self, v0: &Point, v1: &Point, v2: &Point, color: Color) { + /// Draws a triangle to the screen with the given points `(v0, v1, v2)` + /// and the given `color`. + /// + /// **Note:** This function will clip any pixels that are + /// not contained within the screen coordinates. + /// `x < 0 || x >= self.get_width() || y < 0 || y >= self.get_height()`. + fn draw_triangle(&mut self, v0: Point, v1: Point, v2: Point, color: Color) { let screen_width = self.get_width() as i32; let screen_height = self.get_height() as i32; let mut min_x = min(v0.x, min(v1.x, v2.x)); @@ -29,9 +43,9 @@ where for x in min_x..=max_x { for y in min_y..=max_y { let p = Point::new(x, y); - let w0 = orient2d(v1, v2, &p); - let w1 = orient2d(v2, v0, &p); - let w2 = orient2d(&v0, &v1, &p); + let w0 = orient2d(v1, v2, p); + let w1 = orient2d(v2, v0, p); + let w2 = orient2d(v0, v1, p); if w0 >= 0 && w1 >= 0 && w2 >= 0 { self.set_pixel(x as usize, y as usize, color); @@ -40,10 +54,14 @@ where } } + /// Copies the screen buffer in the `GraphicsWriter` to vga memory. + /// + /// **Note:** No draw calls will be displayed on the screen unless + /// this method is called. fn present(&self); } #[inline] -fn orient2d(a: &Point, b: &Point, c: &Point) -> i32 { +fn orient2d(a: Point, b: Point, c: Point) -> i32 { (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) } diff --git a/src/drawing/mod.rs b/src/drawing/mod.rs index 8f1c9f9..122539d 100644 --- a/src/drawing/mod.rs +++ b/src/drawing/mod.rs @@ -13,11 +13,14 @@ use octant::Octant; /// A point in 2D space. #[derive(Copy, Clone)] pub struct Point { + /// The x coordinate of the `Point`. pub x: T, + /// The y coordinate of the `Point`. pub y: T, } impl Point { + /// Creates a new `Point` with the given `(x, y)` coordinates. pub fn new(x: T, y: T) -> Point { Point { x, y } } diff --git a/src/lib.rs b/src/lib.rs index c90ef6a..afd3dd1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ extern crate alloc; pub mod colors; pub mod configurations; +#[cfg(feature = "alloc")] pub mod drawing; pub mod fonts; pub mod registers; diff --git a/src/registers/general.rs b/src/registers/general.rs index 78da603..d63679a 100644 --- a/src/registers/general.rs +++ b/src/registers/general.rs @@ -44,6 +44,8 @@ impl GeneralRegisters { } } + /// Reads the current value from the input status 1 register + /// as specified by the `emulation_mode`. pub fn read_st01(&mut self, emulation_mode: EmulationMode) -> u8 { match emulation_mode { EmulationMode::Cga => unsafe { self.st01_read_cga.read() }, diff --git a/src/writers/mod.rs b/src/writers/mod.rs index 7ecc65d..c5fca77 100644 --- a/src/writers/mod.rs +++ b/src/writers/mod.rs @@ -186,6 +186,9 @@ pub trait GraphicsWriter { /// Clears the screen by setting all pixels to the specified `color`. fn clear_screen(&mut self, color: Color); /// Sets the given pixel at `(x, y)` to the given `color`. + /// + /// **Note:** This does no bounds checking and will panick if + /// `x >= self.get_width() || y >= self.get_height()`. fn set_pixel(&mut self, x: usize, y: usize, color: Color); /// Sets the graphics device to a `VideoMode`. fn set_mode(&self);