From 1668db2c858a1697522dd4f1c3e4faf891fab8d4 Mon Sep 17 00:00:00 2001 From: Victoria Fischer Date: Wed, 30 Oct 2024 20:48:00 +0100 Subject: [PATCH] lib8: drop custom RGB8 struct for rgb crate --- src/TODO.md | 2 +- src/lib8.rs | 82 +++++++++++-------------------------------- src/main.rs | 21 ++++++----- src/power.rs | 17 +++++++++ src/render.rs | 2 +- src/smart_leds_lib.rs | 5 ++- 6 files changed, 54 insertions(+), 75 deletions(-) diff --git a/src/TODO.md b/src/TODO.md index dbffb58..473dd04 100644 --- a/src/TODO.md +++ b/src/TODO.md @@ -1,6 +1,6 @@ [x] cfg macros [ ] warnings -[ ] rgb crate +[x] rgb crate [ ] Layer blending [ ] Refactor idle pattern into test pattern [ ] Wifi diff --git a/src/lib8.rs b/src/lib8.rs index 6746789..c3184f2 100644 --- a/src/lib8.rs +++ b/src/lib8.rs @@ -1,65 +1,41 @@ -use palette::convert::FromColorUnclamped; use palette::encoding::srgb::Srgb; -use palette::Hsv; -use crate::power::AsMilliwatts; +use rgb::RGB8; -#[derive(PartialEq, Debug, Copy, Clone)] -pub struct RGB8 { - pub red: u8, - pub green: u8, - pub blue: u8 +pub trait IntoRgb8 { + fn into_rgb8(self) -> RGB8; } -impl RGB8 { - pub const fn new(red : u8, green : u8, blue : u8) -> Self { - Self { - red: red, - green: green, - blue: blue - } +impl IntoRgb8 for RGB8 { + fn into_rgb8(self) -> RGB8 { + self } } -impl FromColorUnclamped> for RGB8 { - fn from_color_unclamped(hsv: Hsv) -> RGB8 { - if hsv.saturation == 0 { - return RGB8::new(hsv.value, hsv.value, hsv.value); +impl IntoRgb8 for palette::Hsv { + fn into_rgb8(self) -> RGB8 { + if self.saturation == 0 { + return RGB8::new(self.value, self.value, self.value); } - let region = hsv.hue.into_inner() / 43; - let remainder = (hsv.hue.into_inner() - (region * 43)) * 6; + let region = self.hue.into_inner() / 43; + let remainder = (self.hue.into_inner() - (region * 43)) * 6; - let p = hsv.value.wrapping_mul(255 - hsv.saturation).wrapping_shr(8); - let q = (hsv.value.wrapping_mul(255 - ((hsv.saturation.wrapping_mul(remainder)).wrapping_shr(8)))).wrapping_shr(8); - let t = (hsv.value.wrapping_mul(255 - ((hsv.saturation.wrapping_mul(255 - remainder)).wrapping_shr(8)))).wrapping_shr(8); + let p = self.value.wrapping_mul(255 - self.saturation).wrapping_shr(8); + let q = (self.value.wrapping_mul(255 - ((self.saturation.wrapping_mul(remainder)).wrapping_shr(8)))).wrapping_shr(8); + let t = (self.value.wrapping_mul(255 - ((self.saturation.wrapping_mul(255 - remainder)).wrapping_shr(8)))).wrapping_shr(8); match region { - 0 => RGB8::new(hsv.value, t, p), - 1 => RGB8::new(q, hsv.value, p), - 2 => RGB8::new(p, hsv.value, t), - 3 => RGB8::new(p, q, hsv.value), - 4 => RGB8::new(t, p, hsv.value), - _ => RGB8::new(hsv.value, p, q) + 0 => RGB8::new(self.value, t, p), + 1 => RGB8::new(q, self.value, p), + 2 => RGB8::new(p, self.value, t), + 3 => RGB8::new(p, q, self.value), + 4 => RGB8::new(t, p, self.value), + _ => RGB8::new(self.value, p, q) } } } -impl AsMilliwatts for RGB8 { - fn as_milliwatts(&self) -> u32 { - const RED_MW : u32 = 16 * 5; //< 16mA @ 5v = 80mW - const GREEN_MW : u32 = 11 * 5; //< 11mA @ 5v = 55mW - const BLUE_MW : u32 = 15 * 5; //< 15mA @ 5v = 75mW - const DARK_MW : u32 = 1 * 5; //< 1mA @ 5v = 5mW - - let red = (self.red as u32 * RED_MW).wrapping_shr(8); - let green = (self.green as u32 * GREEN_MW).wrapping_shr(8); - let blue = (self.blue as u32 * BLUE_MW).wrapping_shr(8); - - return red + green + blue + DARK_MW; - } -} - #[cfg(feature="embedded-graphics")] mod embedded_graphics { use embedded_graphics::pixelcolor::RgbColor; @@ -90,20 +66,4 @@ mod embedded_graphics { impl PixelColor for RGB8 { type Raw = RawU8; } - - - impl AsMilliwatts for T { - fn as_milliwatts(&self) -> u32 { - const RED_MW : u32 = 16 * 5; //< 16mA @ 5v = 80mW - const GREEN_MW : u32 = 11 * 5; //< 11mA @ 5v = 55mW - const BLUE_MW : u32 = 15 * 5; //< 15mA @ 5v = 75mW - const DARK_MW : u32 = 1 * 5; //< 1mA @ 5v = 5mW - - let red = (self.r() as u32 * RED_MW).wrapping_shr(8); - let green = (self.g() as u32 * GREEN_MW).wrapping_shr(8); - let blue = (self.b() as u32 * BLUE_MW).wrapping_shr(8); - - return red + green + blue + DARK_MW; - } - } } diff --git a/src/main.rs b/src/main.rs index 411b8f8..ea6f7ef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use palette::Hsv; -use palette::convert::IntoColorUnclamped; + +use rgb::RGB8; mod power; mod lib8; @@ -9,6 +10,14 @@ mod time; mod geometry; mod platform; + +use crate::time::Periodically; +use crate::geometry::{Coordinates, VirtualCoordinates}; +use crate::render::{Shader, Surfaces, Surface}; +use crate::task::Task; +use crate::platform::DisplayInit; +use crate::lib8::IntoRgb8; + #[cfg(feature="embedded-graphics")] mod embedded_graphics_lib; @@ -27,12 +36,6 @@ use ws2812_esp32_rmt_driver::lib_smart_leds::Ws2812Esp32Rmt; #[cfg(feature="smart-leds")] use crate::smart_leds_lib::spi::SPIDisplay; -use crate::time::Periodically; -use crate::geometry::{Coordinates, VirtualCoordinates}; -use crate::render::{Shader, Surfaces, Surface}; -use crate::task::Task; -use crate::platform::DisplayInit; - #[cfg(feature="threads")] use crate::render::SharedSurface; @@ -50,8 +53,8 @@ struct IdleShader { } impl Shader for IdleShader { - fn draw(&self, coords: VirtualCoordinates) -> lib8::RGB8 { - Hsv::new_srgb(self.frame.wrapping_add(coords.x()).wrapping_add(coords.y()), 255, 255).into_color_unclamped() + fn draw(&self, coords: VirtualCoordinates) -> RGB8 { + Hsv::new_srgb(self.frame.wrapping_add(coords.x()).wrapping_add(coords.y()), 255, 255).into_rgb8() } } diff --git a/src/power.rs b/src/power.rs index b40cb6a..c7524a7 100644 --- a/src/power.rs +++ b/src/power.rs @@ -1,7 +1,24 @@ +use rgb::RGB8; + pub trait AsMilliwatts { fn as_milliwatts(&self) -> u32; } +impl AsMilliwatts for RGB8 { + fn as_milliwatts(&self) -> u32 { + const RED_MW : u32 = 16 * 5; //< 16mA @ 5v = 80mW + const GREEN_MW : u32 = 11 * 5; //< 11mA @ 5v = 55mW + const BLUE_MW : u32 = 15 * 5; //< 15mA @ 5v = 75mW + const DARK_MW : u32 = 1 * 5; //< 1mA @ 5v = 5mW + + let red = (self.r as u32 * RED_MW).wrapping_shr(8); + let green = (self.g as u32 * GREEN_MW).wrapping_shr(8); + let blue = (self.b as u32 * BLUE_MW).wrapping_shr(8); + + return red + green + blue + DARK_MW; + } +} + pub fn brightness_for_mw(total_mw : u32, target : u8, max_power: u32) -> u8 { let target32 = target as u32; let requested_mw = (total_mw * target32) / 256; diff --git a/src/render.rs b/src/render.rs index 3ffd3c1..80ff5f3 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,11 +1,11 @@ use std::rc::Rc; use std::cell::RefCell; use std::io; +use rgb::RGB8; #[cfg(feature="threads")] use std::sync::{Arc, Mutex}; -use crate::lib8::RGB8; use crate::geometry::*; pub trait Shader: Send { diff --git a/src/smart_leds_lib.rs b/src/smart_leds_lib.rs index 7b88fab..88cbee2 100644 --- a/src/smart_leds_lib.rs +++ b/src/smart_leds_lib.rs @@ -5,7 +5,6 @@ use crate::render::{Surface, SurfacePool, Display, Surfaces}; use crate::task::Task; use crate::power::{brightness_for_mw, AsMilliwatts}; use crate::time::Periodically; -use crate::lib8::RGB8; use crate::geometry::*; use smart_leds::brightness; @@ -77,14 +76,14 @@ impl>, S: Surface> Display for SmartLedDisp fn render_frame(&mut self) { for x in 0..self.pixbuf.len() { let virt_coords = VirtualCoordinates::new(x as u8, 0); - let mut pixel = RGB8::new(0, 0, 0); + let mut pixel = Rgb::new(0, 0, 0); for surface in self.surfaces.iter() { surface.with_shader(|shader| { pixel = shader.draw(virt_coords.clone()); }) } self.total_mw += pixel.as_milliwatts(); - self.pixbuf[x] = Rgb::new(pixel.red, pixel.green, pixel.blue); + self.pixbuf[x] = Rgb::new(pixel.r, pixel.g, pixel.b); }; } }