Skip to content

Commit

Permalink
feat: fix my brokey code and test color map, it works now :)
Browse files Browse the repository at this point in the history
  • Loading branch information
nenikitov committed Nov 20, 2023
1 parent 7125615 commit 570d103
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 55 deletions.
108 changes: 54 additions & 54 deletions engine/src/asset/color_map.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use super::{Asset, Extension, Kind};
use crate::utils::nom::*;

Check warning on line 2 in engine/src/asset/color_map.rs

View workflow job for this annotation

GitHub Actions / clippy

usage of wildcard import

warning: usage of wildcard import --> engine/src/asset/color_map.rs:2:5 | 2 | use crate::utils::nom::*; | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::utils::nom::{Result, multi, number}` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports = note: `-W clippy::wildcard-imports` implied by `-W clippy::pedantic` = help: to override `-W clippy::pedantic` add `#[allow(clippy::wildcard_imports)]`

const COLORS_COUNT: usize = 256;
const SHADES_COUNT: usize = 32;

// TODO(nenikitov): Potentially move to a separate module
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Color {
pub r: u8,
pub g: u8,
Expand All @@ -12,7 +14,23 @@ pub struct Color {

pub struct ColorMap {
// TODO(nenikitov): This probably shouldn't be `pub` and should have an accessor that will hide the "ugly" internal 2D-array structure
pub shades: Box<[[u8; COLORS_COUNT]; SHADES_COUNT]>,
pub shades: Box<[[Color; COLORS_COUNT]; SHADES_COUNT]>,
}

#[allow(clippy::cast_possible_truncation)]
fn shade(input: &[u8]) -> Result<Color> {
let (input, color) = number::le_u32(input)?;
assert!(color <= 0xFFF, "12 bit color is smaller than 0xFFF");

let r = (color & 0xF00) >> 8;
let g = (color & 0x0F0) >> 4;
let b = color & 0x00F;

let r = (r | r << 4) as u8;
let g = (g | g << 4) as u8;
let b = (b | b << 4) as u8;

Ok((input, Color { r, g, b }))
}

impl Asset for ColorMap {
Expand All @@ -21,92 +39,74 @@ impl Asset for ColorMap {
}

fn parse(bytes: &[u8], extension: Extension) -> Self {
// TODO(nenikitov): figure out how to import `nom` and fix compilation issues
fn colors(input: &[u8]) -> Option<[Color; COLORS_COUNT]> {
fn shade(input: &[u8]) -> Option<Color> {
let color = number::le_u32(input)?;
if color >= 0xFFF {
return None;
}

let r = (color & 0xF00) >> 8;
let g = (color & 0x0F0) >> 4;
let b = color & 0x00F;

let r = (r | r << 4) as u8;
let g = (g | g << 4) as u8;
let b = (b | b << 4) as u8;

Some(Color { r, g, b })
}

multi::count(shade, COLORS_COUNT)(input)
fn colors(input: &[u8]) -> Result<[Color; COLORS_COUNT]> {
multi::count_const::<COLORS_COUNT, _, _, _>(shade)(input)
}

assert!(extension == Extension::Dat);
// TODO(nenikitov): Remove `expect()` when parsing changes to return errors
multi::count(colors, SHADES_COUNT)(input)
.expect("Color map is of correct format (256x32 array of 12-bit colors)")
let (_, colors) = multi::count_const::<SHADES_COUNT, _, _, _>(colors)(bytes)
.expect("Color map is of correct format (256x32 array of 12-bit colors)");

Self {
shades: Box::new(colors),
}
}
}

#[cfg(test)]
mod tests {
use super::*;
const COLORS: [(u8, Color); 6] = [
(
0x100,

#[test]
fn parse_works() {
assert_eq!(
shade(&u32::to_le_bytes(0x100)).unwrap().1,
Color {
r: 0x11,
g: 0,
b: 0,
b: 0
},
),
(
0x010,
);
assert_eq!(
shade(&u32::to_le_bytes(0x011)).unwrap().1,
Color {
r: 0,
g: 0x11,
b: 0,
b: 0x11
},
),
(
0x001,
);
assert_eq!(
shade(&u32::to_le_bytes(0x001)).unwrap().1,
Color {
r: 0,
g: 0,
b: 0x11,
b: 0x11
},
),
(
0x220,
);
assert_eq!(
shade(&u32::to_le_bytes(0x220)).unwrap().1,
Color {
r: 0x22,
g: 0x22,
b: 0,
b: 0x00
},
),
(
0x022,
);
assert_eq!(
shade(&u32::to_le_bytes(0x022)).unwrap().1,
Color {
r: 0,
g: 0x22,
b: 0x22,
b: 0x22
},
),
(
0x333,
);
assert_eq!(
shade(&u32::to_le_bytes(0x333)).unwrap().1,
Color {
r: 0x33,
g: 0x33,
b: 0x33,
b: 0x33
},
),
];

#[test]
fn parse_works() {
fn create_color(color: u8, brightness: u8) {
}
);
}
}
2 changes: 1 addition & 1 deletion engine/src/asset/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod gamma_table;
pub mod color_map;
pub mod gamma_table;

#[derive(Clone, Copy, Debug)]
pub enum Kind {
Expand Down
21 changes: 21 additions & 0 deletions engine/src/utils/nom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,28 @@ re_export!(character);
re_export!(number);

pub mod multi {
use std::mem::MaybeUninit;

pub use nom::multi::*;

// TODO(nenikitov): Find a better way to do it without using 3 generics so we don't have to call with `_, _, _`
// Maybe remove `I` and `E` because we are only using `&[u8]` input and our own error type.
pub fn count_const<const COUNT: usize, I, O, E>(
mut f: impl nom::Parser<I, O, E>,
) -> impl FnMut(I) -> nom::IResult<I, [O; COUNT], E>
where
I: Clone + PartialEq,
E: nom::error::ParseError<I>,
{
let mut f = nom::multi::count(f, COUNT);
move |i: I| {
let (i, items) = f(i)?;
match items.try_into() {
Ok(items) => Ok((i, items)),
Err(_) => unreachable!(),
}
}
}
}

pub type Result<'a, T> = nom::IResult<&'a [u8], T>;

0 comments on commit 570d103

Please sign in to comment.