diff --git a/src/graphics/color.rs b/src/graphics/color.rs new file mode 100644 index 0000000..f30ae53 --- /dev/null +++ b/src/graphics/color.rs @@ -0,0 +1,74 @@ +use byteorder::BigEndian; +use crate::misc::emulator_error::EmulatorError; +use crate::misc::endian::MemoryOperations; +use crate::misc::result::EmulatorResult; + +pub struct Color(u8); + +const RED_MULT: u8 = 36; +const GREEN_MULT: u8 = 6; + +impl Color { + /// Only first 216 color indices are used. + const COLOR_MAX:u8 = 215; + const COLOR_FACTOR_8_BIT: u8 = 0x33; + /// This constructs a valid color from rgb triplet + pub fn from_rgb(red: u8, green: u8, blue: u8) -> Color { + let red = red / Self::COLOR_FACTOR_8_BIT; + let green = green / Self::COLOR_FACTOR_8_BIT; + let blue = blue / Self::COLOR_FACTOR_8_BIT; + Color(red * RED_MULT + green * GREEN_MULT + blue) + } + pub fn try_new(in_mem_color: u8) -> EmulatorResult { + if in_mem_color > Self::COLOR_MAX { + return Err(EmulatorError::InvalidColorError(in_mem_color)) + } + Ok(Color(in_mem_color)) + } + pub fn get_mem_byte(&self) -> u8 { + self.0 + } + /// This fetches the rgb triplet + pub fn get_rgb(self) -> [u8; 3] { + let r = self.0 / RED_MULT; + let gb_byte_remainder = self.0 % RED_MULT; + let g = gb_byte_remainder / GREEN_MULT; + let b = gb_byte_remainder % GREEN_MULT; + [r * Self::COLOR_FACTOR_8_BIT, g * Self::COLOR_FACTOR_8_BIT, b * Self::COLOR_FACTOR_8_BIT] + } +} + + +#[cfg(test)] +mod tests { + use crate::graphics::color::Color; + + #[test] + pub fn test_from_mem_zero() { + let color = Color::try_new(0).unwrap(); + assert_eq!([0u8; 3], color.get_rgb()) + } + + #[test] + pub fn test_from_mem_invalid() { + let color = Color::try_new(0xff); + assert!(color.is_err()) + } + #[test] + pub fn test_from_mem_max(){ + let color = Color::try_new(Color::COLOR_MAX).unwrap(); + assert_eq!([255u8;3],color.get_rgb()) + } + + #[test] + pub fn from_rgb_zero(){ + let color = Color::from_rgb(0,0,0); + assert_eq!(0,color.get_mem_byte()) + } + #[test] + pub fn from_rgb_max(){ + let color = Color::from_rgb(255,255,255); + assert_eq!(Color::COLOR_MAX,color.get_mem_byte()) + } + +} \ No newline at end of file diff --git a/src/graphics/mod.rs b/src/graphics/mod.rs new file mode 100644 index 0000000..796176b --- /dev/null +++ b/src/graphics/mod.rs @@ -0,0 +1 @@ +pub mod color; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d77dd0d..6638896 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,12 +3,14 @@ use crate::emu::iomem::MemoryMappedIO; use crate::emu::mem::RamMemory; use crate::emu::mmu::{Memory, MappedMemory}; use crate::misc::emulator_error::EmulatorError; +use crate::misc::result::EmulatorResult; mod emu; mod args; mod misc; +mod graphics; -fn main() ->Result<(),EmulatorError> { +fn main() -> EmulatorResult<()> { SimpleLogger::new().env().init().unwrap(); let mmio = MemoryMappedIO::new(); @@ -17,5 +19,6 @@ fn main() ->Result<(),EmulatorError> { for i in 0..10 { log::info!("Memory at {} is {}",i,mmu.try_get_byte(i)?); } + Ok(()) } diff --git a/src/misc/emulator_error.rs b/src/misc/emulator_error.rs index c2e1efc..ee1e3b8 100644 --- a/src/misc/emulator_error.rs +++ b/src/misc/emulator_error.rs @@ -13,6 +13,7 @@ pub enum DeviceType { pub enum EmulatorError { AllocationError(DeviceType, &'static str), UnreachableMemoryError(DeviceType, u32), + InvalidColorError(u8) }