snes_gfx/
palette.rs

1use std::io::Cursor;
2
3use byteorder::{LittleEndian, ReadBytesExt};
4
5#[derive(Clone, Copy)]
6pub enum Format {
7    BPP2,
8    BPP4,
9    BPP8
10}
11#[derive(Clone, Copy)]
12pub struct RGBColor{
13    pub red:u8,
14    pub green:u8,
15    pub blue:u8
16}
17
18#[derive(Clone)]
19pub struct Palette {
20    colors: Vec<RGBColor>,
21}
22
23impl Palette {
24    pub fn get_rgb_color(&self, palette_index: u8, color: u8) -> RGBColor {
25        self.colors[((palette_index * 16) + color) as usize]
26    }
27
28    pub fn count_palettes(&self) -> u8 {
29        (self.colors.len() / 16).try_into().unwrap()
30    }
31}
32
33impl Palette {
34    fn rgb15_to_rgb24(color: u16) -> RGBColor {
35        let red = 8 * (color & 0x1f) as u16;
36        let green = 8 * ((color & 0x3e0) >> 5) as u16;
37        let blue = 8 * ((color & 0x7c00) >> 10) as u16;
38
39        let red = (red + red / 32) as u8;
40        let green = (green + green / 32) as u8;
41        let blue = (blue + blue / 32) as u8;
42
43        RGBColor{red, green, blue}
44    }
45
46    /// Loads little-endian palette data.
47    pub fn new(palette_data: &[u8]) -> Self {
48        let mut colors: Vec<RGBColor> = Vec::new();
49        let mut cursor = Cursor::new(palette_data);
50        loop {
51            match cursor.read_u16::<LittleEndian>() {
52                Ok(word) => colors.push(Palette::rgb15_to_rgb24(word)),
53                Err(_) => break,
54            }
55        }
56        return Self { colors };
57    }
58}