diff --git a/src/colors.rs b/src/colors.rs index 11ad75c..85c8707 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -4,7 +4,7 @@ pub const PALETTE_SIZE: usize = 768; /// Represents a 16 bit color used for vga display. -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[repr(u8)] pub enum Color16 { /// Represents the color `Black (0x0)`. @@ -48,7 +48,7 @@ impl From for u8 { } /// Represents a color for vga text modes. -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct TextModeColor(u8); diff --git a/src/writers/graphics_320x200x256.rs b/src/writers/graphics_320x200x256.rs index 93e6f2f..e2c8cc0 100644 --- a/src/writers/graphics_320x200x256.rs +++ b/src/writers/graphics_320x200x256.rs @@ -33,24 +33,13 @@ const SIZE: usize = WIDTH * HEIGHT; /// mode.draw_character(118 + offset * 8, 27, character, 255); /// } /// ``` -#[derive(Default)] -pub struct Graphics320x200x256 {} +#[derive(Debug, Clone, Copy, Default)] +pub struct Graphics320x200x256; impl Screen for Graphics320x200x256 { - #[inline] - fn get_width(&self) -> usize { - WIDTH - } - - #[inline] - fn get_height(&self) -> usize { - HEIGHT - } - - #[inline] - fn get_size(&self) -> usize { - SIZE - } + const WIDTH: usize = WIDTH; + const HEIGHT: usize = HEIGHT; + const SIZE: usize = SIZE; } impl GraphicsWriter for Graphics320x200x256 { @@ -101,14 +90,14 @@ impl GraphicsWriter for Graphics320x200x256 { impl Graphics320x200x256 { /// Creates a new `Graphics320x200x256`. - pub fn new() -> Graphics320x200x256 { - Graphics320x200x256 {} + pub const fn new() -> Graphics320x200x256 { + Graphics320x200x256 } /// Returns the start of the `FrameBuffer` as `*mut u8` as /// well as a lock to the vga driver. This ensures the vga /// driver stays locked while the frame buffer is in use. - fn get_frame_buffer(&self) -> (SpinlockGuard, *mut u8) { + fn get_frame_buffer(self) -> (SpinlockGuard<'static, Vga>, *mut u8) { let mut vga = VGA.lock(); let frame_buffer = vga.get_frame_buffer(); (vga, u32::from(frame_buffer) as *mut u8) diff --git a/src/writers/graphics_640x480x16.rs b/src/writers/graphics_640x480x16.rs index 8000b6b..43a42b0 100644 --- a/src/writers/graphics_640x480x16.rs +++ b/src/writers/graphics_640x480x16.rs @@ -36,19 +36,13 @@ const WIDTH_IN_BYTES: usize = WIDTH / 8; /// mode.draw_character(270 + offset * 8, 72, character, Color16::White) /// } /// ``` -#[derive(Default)] +#[derive(Debug, Clone, Copy, Default)] pub struct Graphics640x480x16; impl Screen for Graphics640x480x16 { - fn get_width(&self) -> usize { - WIDTH - } - fn get_height(&self) -> usize { - HEIGHT - } - fn get_size(&self) -> usize { - SIZE - } + const WIDTH: usize = WIDTH; + const HEIGHT: usize = HEIGHT; + const SIZE: usize = SIZE; } impl GraphicsWriter for Graphics640x480x16 { @@ -108,11 +102,11 @@ impl GraphicsWriter for Graphics640x480x16 { impl Graphics640x480x16 { /// Creates a new `Graphics640x480x16`. - pub fn new() -> Graphics640x480x16 { - Graphics640x480x16 {} + pub const fn new() -> Graphics640x480x16 { + Graphics640x480x16 } - fn set_write_mode_0(&self, color: Color16) { + fn set_write_mode_0(self, color: Color16) { let (mut vga, _frame_buffer) = self.get_frame_buffer(); vga.graphics_controller_registers.write_set_reset(color); vga.graphics_controller_registers @@ -121,7 +115,7 @@ impl Graphics640x480x16 { .set_write_mode(WriteMode::Mode0); } - fn set_write_mode_2(&self) { + fn set_write_mode_2(self) { let (mut vga, _frame_buffer) = self.get_frame_buffer(); vga.graphics_controller_registers .set_write_mode(WriteMode::Mode2); @@ -133,14 +127,14 @@ impl Graphics640x480x16 { /// Returns the start of the `FrameBuffer` as `*mut u8` as /// well as a lock to the vga driver. This ensures the vga /// driver stays locked while the frame buffer is in use. - fn get_frame_buffer(&self) -> (SpinlockGuard, *mut u8) { + fn get_frame_buffer(self) -> (SpinlockGuard<'static, Vga>, *mut u8) { let mut vga = VGA.lock(); let frame_buffer = vga.get_frame_buffer(); (vga, u32::from(frame_buffer) as *mut u8) } #[inline] - fn _set_pixel(&self, x: usize, y: usize, color: Color16) { + fn _set_pixel(self, x: usize, y: usize, color: Color16) { let (mut vga, frame_buffer) = self.get_frame_buffer(); let offset = x / 8 + y * WIDTH_IN_BYTES; let pixel_mask = 0x80 >> (x & 0x07); diff --git a/src/writers/mod.rs b/src/writers/mod.rs index c6c6efa..d47a2a8 100644 --- a/src/writers/mod.rs +++ b/src/writers/mod.rs @@ -20,7 +20,7 @@ pub use text_40x50::Text40x50; pub use text_80x25::Text80x25; /// Represents a `ScreenCharacter` in vga text modes. -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[repr(C)] pub struct ScreenCharacter { character: u8, @@ -29,7 +29,7 @@ pub struct ScreenCharacter { impl ScreenCharacter { /// Creates a new `ScreenCharacter` with the specified `character` and `TextModeColor`. - pub fn new(character: u8, color: TextModeColor) -> ScreenCharacter { + pub const fn new(character: u8, color: TextModeColor) -> ScreenCharacter { ScreenCharacter { character, color } } @@ -51,12 +51,12 @@ static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter { /// A helper trait used to interact with various vga screens. pub trait Screen { - /// Returns the width of the `Screen`. - fn get_width(&self) -> usize; - /// Returns the height of the `Screen`. - fn get_height(&self) -> usize; - /// Returns the size of the `Screen`. - fn get_size(&self) -> usize; + /// The width of the `Screen`. + const WIDTH: usize; + /// The height of the `Screen`. + const HEIGHT: usize; + /// The size (total area) of the `Screen`. + const SIZE: usize; } /// A helper trait used to interact with various vga text modes. @@ -78,11 +78,15 @@ pub trait TextWriter: Screen { /// a background color of `Color16::Black` and a foreground /// color of `Color16::Yellow`. fn clear_screen(&self) { + self.fill_screen(BLANK_CHARACTER); + } + + /// Fills the screen by setting all cells to the given screen character. + fn fill_screen(&self, character: ScreenCharacter) { let (_vga, frame_buffer) = self.get_frame_buffer(); - let screen_size = self.get_width() * self.get_height(); - for i in 0..screen_size { + for i in 0..Self::SIZE { unsafe { - frame_buffer.add(i).write_volatile(BLANK_CHARACTER); + frame_buffer.add(i).write_volatile(character); } } } @@ -118,7 +122,7 @@ pub trait TextWriter: Screen { /// Returns the `ScreenCharacter` at the given `(x, y)` position. fn read_character(&self, x: usize, y: usize) -> ScreenCharacter { let (_vga, frame_buffer) = self.get_frame_buffer(); - let offset = self.get_width() * y + x; + let offset = Self::WIDTH * y + x; unsafe { frame_buffer.add(offset).read_volatile() } } @@ -154,7 +158,7 @@ pub trait TextWriter: Screen { /// Sets the current text cursor to the position specified by /// `x` and `y`. fn set_cursor_position(&self, x: usize, y: usize) { - let offset = self.get_width() * y + x; + let offset = Self::WIDTH * y + x; let (mut vga, _frame_buffer) = self.get_frame_buffer(); let emulation_mode = vga.get_emulation_mode(); let cursor_start = offset & 0xFF; @@ -174,7 +178,7 @@ pub trait TextWriter: Screen { /// Prints the given `character` and `color` at `(x, y)`. fn write_character(&self, x: usize, y: usize, screen_character: ScreenCharacter) { let (_vga, frame_buffer) = self.get_frame_buffer(); - let offset = self.get_width() * y + x; + let offset = Self::WIDTH * y + x; unsafe { frame_buffer.add(offset).write_volatile(screen_character); } diff --git a/src/writers/text_40x25.rs b/src/writers/text_40x25.rs index 452d2d8..6c3e758 100644 --- a/src/writers/text_40x25.rs +++ b/src/writers/text_40x25.rs @@ -7,6 +7,7 @@ use crate::{ const WIDTH: usize = 40; const HEIGHT: usize = 25; +const SIZE: usize = WIDTH * HEIGHT; /// A basic interface for interacting with vga text mode 40x25 /// @@ -26,21 +27,13 @@ const HEIGHT: usize = 25; /// text_mode.clear_screen(); /// text_mode.write_character(0, 0, screen_character); /// ``` -#[derive(Default)] +#[derive(Debug, Clone, Copy, Default)] pub struct Text40x25; impl Screen for Text40x25 { - fn get_width(&self) -> usize { - WIDTH - } - - fn get_height(&self) -> usize { - HEIGHT - } - - fn get_size(&self) -> usize { - WIDTH * HEIGHT - } + const WIDTH: usize = WIDTH; + const HEIGHT: usize = HEIGHT; + const SIZE: usize = SIZE; } impl TextWriter for Text40x25 { @@ -58,7 +51,7 @@ impl TextWriter for Text40x25 { impl Text40x25 { /// Creates a new `Text40x25`. - pub fn new() -> Text40x25 { - Text40x25 {} + pub const fn new() -> Text40x25 { + Text40x25 } } diff --git a/src/writers/text_40x50.rs b/src/writers/text_40x50.rs index 62b057b..e63c248 100644 --- a/src/writers/text_40x50.rs +++ b/src/writers/text_40x50.rs @@ -7,6 +7,7 @@ use crate::{ const WIDTH: usize = 40; const HEIGHT: usize = 50; +const SIZE: usize = WIDTH * HEIGHT; /// A basic interface for interacting with vga text mode 40x50 /// @@ -26,21 +27,13 @@ const HEIGHT: usize = 50; /// text_mode.clear_screen(); /// text_mode.write_character(0, 0, screen_character); /// ``` -#[derive(Default)] +#[derive(Debug, Clone, Copy, Default)] pub struct Text40x50; impl Screen for Text40x50 { - fn get_width(&self) -> usize { - WIDTH - } - - fn get_height(&self) -> usize { - HEIGHT - } - - fn get_size(&self) -> usize { - WIDTH * HEIGHT - } + const WIDTH: usize = WIDTH; + const HEIGHT: usize = HEIGHT; + const SIZE: usize = SIZE; } impl TextWriter for Text40x50 { @@ -58,7 +51,7 @@ impl TextWriter for Text40x50 { impl Text40x50 { /// Creates a new `Text40x50`. - pub fn new() -> Text40x50 { - Text40x50 {} + pub const fn new() -> Text40x50 { + Text40x50 } } diff --git a/src/writers/text_80x25.rs b/src/writers/text_80x25.rs index 72a4354..72403d0 100644 --- a/src/writers/text_80x25.rs +++ b/src/writers/text_80x25.rs @@ -7,6 +7,7 @@ use crate::{ const WIDTH: usize = 80; const HEIGHT: usize = 25; +const SIZE: usize = WIDTH * HEIGHT; /// A basic interface for interacting with vga text mode 80x25 /// @@ -26,21 +27,13 @@ const HEIGHT: usize = 25; /// text_mode.clear_screen(); /// text_mode.write_character(0, 0, screen_character); /// ``` -#[derive(Default)] +#[derive(Debug, Clone, Copy, Default)] pub struct Text80x25; impl Screen for Text80x25 { - fn get_width(&self) -> usize { - WIDTH - } - - fn get_height(&self) -> usize { - HEIGHT - } - - fn get_size(&self) -> usize { - WIDTH * HEIGHT - } + const WIDTH: usize = WIDTH; + const HEIGHT: usize = HEIGHT; + const SIZE: usize = SIZE; } impl TextWriter for Text80x25 { @@ -57,7 +50,7 @@ impl TextWriter for Text80x25 { impl Text80x25 { /// Creates a new `Text80x25`. - pub fn new() -> Text80x25 { - Text80x25 {} + pub const fn new() -> Text80x25 { + Text80x25 } }