use core::fmt::Display; use alloc::{string::String, vec::Vec}; use num_enum::FromPrimitive; use crate::card::decoder::{Events, decode_known_event, decode_packed_card_text, decode_secret}; use embedded_graphics::pixelcolor::{Rgb565, Rgb888}; #[derive(Debug, Clone, Copy)] pub struct NfcPayload<'a> { pub event_encoding: &'a [u8], pub card_type: u8, pub card_uuid: &'a [u8], pub _reserved: &'a [u8], pub sprite: &'a [u8], pub packed_card_text: &'a [u8], pub secret: &'a [u8], pub _opaque_trailer: &'a [u8], } #[derive(Debug, Clone, Eq, PartialEq, FromPrimitive)] #[repr(u8)] pub enum CardType { #[num_enum(default)] Default = 1, Blueprint = 2, CYBER = 3, Nature = 4, Fossil = 5, Ghost = 6, Daemon = 7, Fairy = 8, } impl Display for CardType { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match *self { CardType::Default => write!(f, "Default"), CardType::Blueprint => write!(f, "Blueprint"), CardType::CYBER => write!(f, "CYBER"), CardType::Nature => write!(f, "Nature"), CardType::Fossil => write!(f, "Fossil"), CardType::Ghost => write!(f, "Ghost"), CardType::Daemon => write!(f, "Daemon"), CardType::Fairy => write!(f, "Fairy"), } } } pub type PrimaryColor = Rgb565; impl From for PrimaryColor { fn from(val: CardType) -> Self { match val { CardType::Default => Rgb888::new(0xD8, 0x68, 0x30).into(), CardType::Blueprint => Rgb888::new(0x6D, 0x81, 0xFF).into(), CardType::CYBER => Rgb888::new(0xFF, 0xFF, 0x04).into(), CardType::Nature => Rgb888::new(0x55, 0xA0, 0x58).into(), CardType::Fossil => Rgb888::new(0xB9, 0x7A, 0x60).into(), CardType::Ghost => Rgb888::new(0xAB, 0xAB, 0xAB).into(), CardType::Daemon => Rgb888::new(0x60, 0x00, 0x88).into(), CardType::Fairy => Rgb888::new(0xB0, 0xA9, 0xE4).into(), } } } pub type Palette = [Rgb565; 16]; impl From for Palette { fn from(val: CardType) -> Self { match val { CardType::Default => [ Rgb888::new(31, 23, 35).into(), Rgb888::new(60, 47, 82).into(), Rgb888::new(178, 39, 65).into(), Rgb888::new(70, 86, 165).into(), Rgb888::new(245, 70, 76).into(), Rgb888::new(216, 104, 48).into(), Rgb888::new(140, 127, 144).into(), Rgb888::new(73, 149, 243).into(), Rgb888::new(62, 197, 75).into(), Rgb888::new(240, 149, 72).into(), Rgb888::new(188, 176, 179).into(), Rgb888::new(247, 156, 136).into(), Rgb888::new(114, 222, 235).into(), Rgb888::new(180, 230, 86).into(), Rgb888::new(239, 208, 129).into(), Rgb888::new(255, 255, 255).into(), ], CardType::Blueprint => [ Rgb888::new(83, 67, 127).into(), Rgb888::new(44, 111, 153).into(), Rgb888::new(142, 88, 111).into(), Rgb888::new(0, 188, 170).into(), Rgb888::new(153, 104, 226).into(), Rgb888::new(109, 129, 255).into(), Rgb888::new(255, 84, 112).into(), Rgb888::new(196, 143, 158).into(), Rgb888::new(168, 159, 204).into(), Rgb888::new(190, 155, 255).into(), Rgb888::new(255, 155, 113).into(), Rgb888::new(127, 206, 255).into(), Rgb888::new(255, 155, 182).into(), Rgb888::new(255, 217, 174).into(), Rgb888::new(255, 217, 232).into(), Rgb888::new(255, 255, 255).into(), ], CardType::CYBER => [ Rgb888::new(0, 0, 0).into(), Rgb888::new(0, 0, 126).into(), Rgb888::new(0, 0, 255).into(), Rgb888::new(126, 0, 0).into(), Rgb888::new(126, 0, 126).into(), Rgb888::new(4, 126, 0).into(), Rgb888::new(254, 0, 0).into(), Rgb888::new(4, 126, 126).into(), Rgb888::new(254, 0, 255).into(), Rgb888::new(126, 126, 0).into(), Rgb888::new(126, 126, 126).into(), Rgb888::new(6, 255, 4).into(), Rgb888::new(6, 255, 255).into(), Rgb888::new(190, 190, 190).into(), Rgb888::new(255, 255, 4).into(), Rgb888::new(255, 255, 255).into(), ], CardType::Nature => [ Rgb888::new(35, 34, 40).into(), Rgb888::new(40, 66, 97).into(), Rgb888::new(30, 116, 83).into(), Rgb888::new(117, 77, 69).into(), Rgb888::new(95, 88, 84).into(), Rgb888::new(36, 133, 166).into(), Rgb888::new(198, 80, 70).into(), Rgb888::new(85, 160, 88).into(), Rgb888::new(135, 133, 115).into(), Rgb888::new(84, 186, 210).into(), Rgb888::new(161, 191, 65).into(), Rgb888::new(230, 146, 138).into(), Rgb888::new(184, 176, 149).into(), Rgb888::new(227, 192, 84).into(), Rgb888::new(195, 213, 199).into(), Rgb888::new(255, 255, 255).into(), ], CardType::Fossil => [ Rgb888::new(75, 61, 68).into(), Rgb888::new(119, 66, 81).into(), Rgb888::new(78, 84, 99).into(), Rgb888::new(100, 83, 85).into(), Rgb888::new(156, 82, 78).into(), Rgb888::new(132, 109, 89).into(), Rgb888::new(91, 125, 115).into(), Rgb888::new(125, 123, 98).into(), Rgb888::new(140, 124, 121).into(), Rgb888::new(185, 122, 96).into(), Rgb888::new(168, 138, 94).into(), Rgb888::new(142, 159, 125).into(), Rgb888::new(170, 162, 93).into(), Rgb888::new(169, 156, 141).into(), Rgb888::new(204, 168, 123).into(), Rgb888::new(255, 255, 255).into(), ], CardType::Ghost => [ Rgb888::new(0, 0, 0).into(), Rgb888::new(24, 24, 24).into(), Rgb888::new(40, 40, 40).into(), Rgb888::new(56, 56, 56).into(), Rgb888::new(71, 71, 71).into(), Rgb888::new(86, 86, 86).into(), Rgb888::new(100, 100, 100).into(), Rgb888::new(113, 113, 113).into(), Rgb888::new(126, 126, 126).into(), Rgb888::new(140, 140, 140).into(), Rgb888::new(155, 155, 155).into(), Rgb888::new(171, 171, 171).into(), Rgb888::new(189, 189, 189).into(), Rgb888::new(209, 209, 209).into(), Rgb888::new(231, 231, 231).into(), Rgb888::new(255, 255, 255).into(), ], CardType::Daemon => [ Rgb888::new(0, 3, 60).into(), Rgb888::new(96, 0, 136).into(), Rgb888::new(0, 56, 132).into(), Rgb888::new(42, 46, 121).into(), Rgb888::new(0, 82, 96).into(), Rgb888::new(177, 5, 133).into(), Rgb888::new(255, 0, 78).into(), Rgb888::new(172, 41, 206).into(), Rgb888::new(0, 157, 74).into(), Rgb888::new(0, 138, 197).into(), Rgb888::new(78, 110, 168).into(), Rgb888::new(255, 92, 255).into(), Rgb888::new(10, 255, 82).into(), Rgb888::new(0, 247, 255).into(), Rgb888::new(173, 212, 250).into(), Rgb888::new(255, 255, 255).into(), ], CardType::Fairy => [ Rgb888::new(40, 40, 46).into(), Rgb888::new(108, 86, 113).into(), Rgb888::new(135, 168, 137).into(), Rgb888::new(249, 130, 132).into(), Rgb888::new(176, 169, 228).into(), Rgb888::new(222, 163, 139).into(), Rgb888::new(172, 204, 228).into(), Rgb888::new(254, 170, 228).into(), Rgb888::new(217, 200, 191).into(), Rgb888::new(255, 195, 132).into(), Rgb888::new(176, 235, 147).into(), Rgb888::new(179, 227, 218).into(), Rgb888::new(233, 245, 157).into(), Rgb888::new(255, 230, 198).into(), Rgb888::new(255, 247, 160).into(), Rgb888::new(255, 255, 255).into(), ], } } } #[derive(Debug, Clone)] pub struct Sprite { pub data: Vec, } #[derive(Debug, Clone)] pub struct Card { pub uuid: String, pub event: Events, pub cardtype: CardType, pub name: String, pub trait1: String, pub trait2: String, pub trait3: String, pub secret: String, pub sprite: Sprite, } impl<'a> TryFrom> for Card { type Error = &'static str; fn try_from(payload: NfcPayload<'a>) -> Result { let uuid: String = "empty for now".into(); //str::from_utf8(payload.card_uuid).unwrap().into(); let event = decode_known_event(payload.event_encoding); let cardtype = CardType::from(payload.card_type); let (name, trait1, trait2, trait3) = decode_packed_card_text(payload.packed_card_text); let secret = decode_secret(payload.secret); let sprite = Sprite { data: payload.sprite.to_vec(), }; Ok(Self { uuid, event, cardtype, name, trait1, trait2, trait3, secret, sprite, }) } }