More alloc and comments

This commit is contained in:
Ryan Kennedy 2020-03-29 17:47:08 -05:00
parent 57799a188b
commit 60ea020282
5 changed files with 33 additions and 6 deletions

View file

@ -2,18 +2,32 @@ use super::Point;
use crate::writers::{GraphicsWriter, Screen}; use crate::writers::{GraphicsWriter, Screen};
use core::cmp::{max, min}; use core::cmp::{max, min};
/// A helper trait used to draw to the vga screen in graphics mode.
pub trait Device<Color> pub trait Device<Color>
where where
Self: Screen + GraphicsWriter<Color>, Self: Screen + GraphicsWriter<Color>,
Color: Clone + Copy, 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); fn draw_character(&mut self, x: usize, y: usize, character: char, color: Color);
/// Draws a line from `start` to `end` with the specified `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<isize>, end: Point<isize>, color: Color); fn draw_line(&mut self, start: Point<isize>, end: Point<isize>, color: Color);
fn draw_triangle(&mut self, v0: &Point<i32>, v1: &Point<i32>, v2: &Point<i32>, 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<i32>, v1: Point<i32>, v2: Point<i32>, color: Color) {
let screen_width = self.get_width() as i32; let screen_width = self.get_width() as i32;
let screen_height = self.get_height() as i32; let screen_height = self.get_height() as i32;
let mut min_x = min(v0.x, min(v1.x, v2.x)); 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 x in min_x..=max_x {
for y in min_y..=max_y { for y in min_y..=max_y {
let p = Point::new(x, y); let p = Point::new(x, y);
let w0 = orient2d(v1, v2, &p); let w0 = orient2d(v1, v2, p);
let w1 = orient2d(v2, v0, &p); let w1 = orient2d(v2, v0, p);
let w2 = orient2d(&v0, &v1, &p); let w2 = orient2d(v0, v1, p);
if w0 >= 0 && w1 >= 0 && w2 >= 0 { if w0 >= 0 && w1 >= 0 && w2 >= 0 {
self.set_pixel(x as usize, y as usize, color); 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); fn present(&self);
} }
#[inline] #[inline]
fn orient2d(a: &Point<i32>, b: &Point<i32>, c: &Point<i32>) -> i32 { fn orient2d(a: Point<i32>, b: Point<i32>, c: Point<i32>) -> i32 {
(b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)
} }

View file

@ -13,11 +13,14 @@ use octant::Octant;
/// A point in 2D space. /// A point in 2D space.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Point<T> { pub struct Point<T> {
/// The x coordinate of the `Point`.
pub x: T, pub x: T,
/// The y coordinate of the `Point`.
pub y: T, pub y: T,
} }
impl<T> Point<T> { impl<T> Point<T> {
/// Creates a new `Point` with the given `(x, y)` coordinates.
pub fn new(x: T, y: T) -> Point<T> { pub fn new(x: T, y: T) -> Point<T> {
Point { x, y } Point { x, y }
} }

View file

@ -12,6 +12,7 @@ extern crate alloc;
pub mod colors; pub mod colors;
pub mod configurations; pub mod configurations;
#[cfg(feature = "alloc")]
pub mod drawing; pub mod drawing;
pub mod fonts; pub mod fonts;
pub mod registers; pub mod registers;

View file

@ -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 { pub fn read_st01(&mut self, emulation_mode: EmulationMode) -> u8 {
match emulation_mode { match emulation_mode {
EmulationMode::Cga => unsafe { self.st01_read_cga.read() }, EmulationMode::Cga => unsafe { self.st01_read_cga.read() },

View file

@ -186,6 +186,9 @@ pub trait GraphicsWriter<Color> {
/// Clears the screen by setting all pixels to the specified `color`. /// Clears the screen by setting all pixels to the specified `color`.
fn clear_screen(&mut self, color: Color); fn clear_screen(&mut self, color: Color);
/// Sets the given pixel at `(x, y)` to the given `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); fn set_pixel(&mut self, x: usize, y: usize, color: Color);
/// Sets the graphics device to a `VideoMode`. /// Sets the graphics device to a `VideoMode`.
fn set_mode(&self); fn set_mode(&self);