From 0e936872094ab8b86a2428bc6d46f35d907667de Mon Sep 17 00:00:00 2001 From: Ryan Kennedy Date: Wed, 18 Mar 2020 20:45:30 -0500 Subject: [PATCH] Initial code for #4 --- src/colors.rs | 24 ++++++++++++++++++++++++ src/writers/mod.rs | 23 +++++++++++++++++++---- src/writers/text_40x25.rs | 5 +++-- src/writers/text_40x50.rs | 5 +++-- src/writers/text_80x25.rs | 5 +++-- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/colors.rs b/src/colors.rs index e6bd956..33e5f89 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -52,6 +52,16 @@ impl TextModeColor { pub const fn new(foreground: Color16Bit, background: Color16Bit) -> TextModeColor { TextModeColor((background as u8) << 4 | (foreground as u8)) } + + /// Sets the background color given the specified `background`; + pub fn set_background(&mut self, background: Color16Bit) { + self.0 = (background as u8) << 4 | (self.0 & 0x0F); + } + + /// Sets the foreground color given the specified `foreground`. + pub fn set_foreground(&mut self, foreground: Color16Bit) { + self.0 = foreground as u8; + } } /// Represents the default vga 256 color palette. @@ -105,3 +115,17 @@ pub const DEFAULT_PALETTE: [u8; PALETTE_SIZE] = [ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, ]; + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_set_foreground() { + let mut color = TextModeColor::new(Color16Bit::Yellow, Color16Bit::Black); + color.set_foreground(Color16Bit::Red); + color.set_background(Color16Bit::DarkGrey); + assert_eq!(color.0 & 0x0F, Color16Bit::Red as u8); + assert_eq!(color.0 >> 4, Color16Bit::DarkGrey as u8); + } +} diff --git a/src/writers/mod.rs b/src/writers/mod.rs index f68050a..b2f497b 100644 --- a/src/writers/mod.rs +++ b/src/writers/mod.rs @@ -25,12 +25,20 @@ pub struct ScreenCharacter { } impl ScreenCharacter { - /// Creates a new `ScreenCharacter` with the specified `character` - /// and a `TextModeColor` with the specified `foreground` and `background`. - pub fn new(character: u8, foreground: Color16Bit, background: Color16Bit) -> ScreenCharacter { - let color = TextModeColor::new(foreground, background); + /// Creates a new `ScreenCharacter` with the specified `character` and `TextModeColor`. + pub fn new(character: u8, color: TextModeColor) -> ScreenCharacter { ScreenCharacter { character, color } } + + /// Returns the `character` associated with the `ScreenCharacter`. + pub fn get_character(&self) -> u8 { + self.character + } + + /// Returns the `color` associated with the `ScreenCharacter`. + pub fn get_color(&self) -> TextModeColor { + self.color + } } static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter { @@ -98,6 +106,13 @@ pub trait TextWriter { ); } + /// 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; + unsafe { frame_buffer.add(offset).read_volatile() } + } + /// Sets the size of the cursor, as specified by `scan_line_start` and `scan_line_end`. /// /// This field controls the appearance of the text mode cursor by specifying the scan diff --git a/src/writers/text_40x25.rs b/src/writers/text_40x25.rs index 3ce2328..5eb92f2 100644 --- a/src/writers/text_40x25.rs +++ b/src/writers/text_40x25.rs @@ -15,11 +15,12 @@ const HEIGHT: usize = 25; /// Basic usage: /// /// ```no_run -/// use vga::colors::Color16Bit; +/// use vga::colors::{Color16Bit, TextModeColor}; /// use vga::writers::{ScreenCharacter, TextWriter, Text40x25}; /// /// let text_mode = Text40x25::new(); -/// let screen_character = ScreenCharacter::new(b'T', Color16Bit::Yellow, Color16Bit::Black); +/// let color = TextModeColor::new(Color16Bit::Yellow, Color16Bit::Black); +/// let screen_character = ScreenCharacter::new(b'T', color); /// /// text_mode.set_mode(); /// text_mode.clear_screen(); diff --git a/src/writers/text_40x50.rs b/src/writers/text_40x50.rs index 0e0397b..ac604f4 100644 --- a/src/writers/text_40x50.rs +++ b/src/writers/text_40x50.rs @@ -15,11 +15,12 @@ const HEIGHT: usize = 50; /// Basic usage: /// /// ```no_run -/// use vga::colors::Color16Bit; +/// use vga::colors::{Color16Bit, TextModeColor}; /// use vga::writers::{ScreenCharacter, TextWriter, Text40x50}; /// /// let text_mode = Text40x50::new(); -/// let screen_character = ScreenCharacter::new(b'T', Color16Bit::Yellow, Color16Bit::Black); +/// let color = TextModeColor::new(Color16Bit::Yellow, Color16Bit::Black); +/// let screen_character = ScreenCharacter::new(b'T', color); /// /// text_mode.set_mode(); /// text_mode.clear_screen(); diff --git a/src/writers/text_80x25.rs b/src/writers/text_80x25.rs index 5dcf524..aadb975 100644 --- a/src/writers/text_80x25.rs +++ b/src/writers/text_80x25.rs @@ -15,11 +15,12 @@ const HEIGHT: usize = 25; /// Basic usage: /// /// ```no_run -/// use vga::colors::Color16Bit; +/// use vga::colors::{Color16Bit, TextModeColor}; /// use vga::writers::{ScreenCharacter, TextWriter, Text80x25}; /// /// let text_mode = Text80x25::new(); -/// let screen_character = ScreenCharacter::new(b'T', Color16Bit::Yellow, Color16Bit::Black); +/// let color = TextModeColor::new(Color16Bit::Yellow, Color16Bit::Black); +/// let screen_character = ScreenCharacter::new(b'T', color); /// /// text_mode.set_mode(); /// text_mode.clear_screen();