use crate::wasm4::DRAW_COLORS;
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum PaletteColor {
Transparent = 0,
P1,
P2,
P3,
P4,
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum DrawColorsIndex {
I1 = 0,
I2,
I3,
I4,
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct DrawColors([u8; 4]);
impl DrawColors {
pub fn builder() -> DrawColorsBuilder {
DrawColorsBuilder::new()
}
}
#[derive(Default)]
pub struct DrawColorsBuilder([u8; 4]);
impl DrawColorsBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn with_index(mut self, index: DrawColorsIndex, value: PaletteColor) -> Self {
self.0[index as usize] = value as u8;
self
}
pub fn build(self) -> DrawColors {
DrawColors(self.0)
}
}
pub struct SystemDrawColors {
_private: (),
}
impl SystemDrawColors {
pub(crate) const fn new() -> Self {
Self { _private: () }
}
pub fn set(&self, colors: DrawColors) {
write_system_draw_colors(colors)
}
pub fn reset(&self) {
self.set(DrawColors::default())
}
pub fn set_index(&self, index: DrawColorsIndex, value: PaletteColor) {
let mut existing = self.get();
existing.0[index as usize] = value as u8;
self.set(existing);
}
pub fn get(&self) -> DrawColors {
read_system_draw_colors()
}
}
impl From<DrawColors> for u16 {
fn from(value: DrawColors) -> Self {
value.0[0] as u16
+ shift_u16(value.0[1], 4)
+ shift_u16(value.0[2], 8)
+ shift_u16(value.0[3], 12)
}
}
impl From<u16> for DrawColors {
fn from(value: u16) -> Self {
let i3 = ((value & 0xf000) >> 12) as u8;
let i2 = ((value & 0x0f00) >> 8) as u8;
let i1 = ((value & 0x00f0) >> 4) as u8;
let i0 = (value & 0x000f) as u8;
Self([i0, i1, i2, i3])
}
}
fn shift_u16(v: u8, amount: u16) -> u16 {
(v as u16) << amount
}
fn read_system_draw_colors() -> DrawColors {
unsafe { (*DRAW_COLORS).into() }
}
fn write_system_draw_colors(colors: DrawColors) {
unsafe { *DRAW_COLORS = u16::from(colors) }
}