diff --git a/Cargo.toml b/Cargo.toml index ed4879b..91d4fe4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vga" -version = "0.1.1" +version = "0.1.2" authors = ["Ryan Kennedy "] edition = "2018" description = "Support for vga specific functions, data structures, and registers." diff --git a/Changelog.md b/Changelog.md new file mode 100644 index 0000000..7b170a9 --- /dev/null +++ b/Changelog.md @@ -0,0 +1,10 @@ +# 0.1.2 + +## Breaking + +- `ScreenCharacter::new` now takes a `TextModeColor` instead of 2 `Color16Bit`. + +## Other +- Added `ScreenCharacter::get_character`. +- Added `ScreenCharacter::get_color`. +- Added `TextWriter::read_character`. diff --git a/src/colors.rs b/src/colors.rs index e6bd956..236c6dc 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,22 @@ 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); + assert_eq!(color.0 & 0x0F, Color16Bit::Red as u8); + } + + #[test] + fn test_set_background() { + let mut color = TextModeColor::new(Color16Bit::Yellow, Color16Bit::Black); + color.set_background(Color16Bit::DarkGrey); + assert_eq!(color.0 >> 4, Color16Bit::DarkGrey as u8); + } +} diff --git a/src/writers/mod.rs b/src/writers/mod.rs index f68050a..02719c2 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();