use core::fmt;
pub const NONE: char = char::REPLACEMENT_CHARACTER;
#[rustfmt::skip]
const PETSCII_TO_CHAR_MAP: [char; 256] = [
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'[', '\u{00A3}', ']', '\u{2191}', '\u{2190}', '\u{2501}',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'\u{254b}', NONE, '\u{2503}', '\u{2592}', NONE,
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
'\u{00a0}', '\u{258c}', '\u{2584}', '\u{2594}',
'\u{2581}', '\u{258e}', '\u{2592}', '\u{2595}',
NONE, NONE, '\u{2595}', '\u{2523}',
'\u{2597}', '\u{2517}', '\u{2513}', '\u{2582}',
'\u{250f}', '\u{253b}', '\u{2533}', '\u{252b}',
'\u{258e}', '\u{258d}', '\u{2595}', '\u{2594}',
'\u{2594}', '\u{2583}', '\u{2713}', '\u{2596}',
'\u{259d}', '\u{2518}', '\u{2598}', '\u{259a}',
'\u{2501}',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'\u{254b}', NONE, '\u{2503}', '\u{2592}', NONE,
'\u{00a0}', '\u{258c}', '\u{2584}', '\u{2594}',
'\u{2581}', '\u{258e}', '\u{2592}', '\u{2595}',
NONE, NONE, '\u{2595}', '\u{2523}',
'\u{2597}', '\u{2517}', '\u{2513}', '\u{2582}',
'\u{250f}', '\u{253b}', '\u{2533}', '\u{252b}',
'\u{258e}', '\u{258d}', '\u{2595}', '\u{2594}',
'\u{2594}', '\u{2583}', '\u{2713}', '\u{2596}',
'\u{259d}', '\u{2518}', '\u{2598}', '\u{2592}',
];
#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)]
pub struct Petscii(u8);
impl Petscii {
pub const fn from_byte(byte: u8) -> Petscii {
Petscii(byte)
}
pub const fn from_char(letter: char) -> Petscii {
let mut petscii = 0;
while petscii < PETSCII_TO_CHAR_MAP.len() {
if letter == PETSCII_TO_CHAR_MAP[petscii] {
return Petscii::from_byte(petscii as u8);
}
petscii += 1;
}
panic!("INVALID LETTER");
}
pub const fn to_screen_code(&self) -> u8 {
match self.0 {
0..=31 => self.0 + 128,
32..=63 => self.0,
64..=95 => self.0 - 64,
96..=127 => self.0 - 32,
128..=159 => self.0 + 64,
160..=191 => self.0 - 64,
192..=254 => self.0 - 128,
255 => 94,
}
}
pub const fn to_char(&self) -> char {
PETSCII_TO_CHAR_MAP[self.0 as usize]
}
pub const fn to_byte(&self) -> u8 {
self.0
}
}
impl From<Petscii> for char {
fn from(petscii: Petscii) -> Self {
petscii.to_char()
}
}
impl From<Petscii> for u8 {
fn from(petscii: Petscii) -> Self {
petscii.0
}
}
impl From<u8> for Petscii {
fn from(value: u8) -> Self {
Petscii::from_byte(value)
}
}
impl From<char> for Petscii {
fn from(value: char) -> Self {
Petscii::from_char(value)
}
}
impl fmt::Display for Petscii {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.to_char())
}
}
#[macro_export]
macro_rules! screen_codes {
($A:expr) => {{
use $crate::petscii::*;
const N: usize = const_str::to_char_array!($A).len();
const CHARS: [char; N] = const_str::to_char_array!($A);
let mut screen_codes = [0u8; N];
let mut i = 0;
while i < N {
let petscii = Petscii::from_char(CHARS[i]);
screen_codes[i] = petscii.to_screen_code();
i += 1;
}
screen_codes
}};
}
#[macro_export]
macro_rules! screen_codes_null {
($A:expr) => {{
use $crate::screen_codes;
*const_str::concat_bytes!(screen_codes!($A), 0u8)
}};
}
#[macro_export]
macro_rules! petscii_codes {
($A:expr) => {{
use $crate::petscii::*;
const N: usize = const_str::to_char_array!($A).len();
const CHARS: [char; N] = const_str::to_char_array!($A);
let mut petscii_bytes = [0u8; N];
let mut i = 0;
while i < N {
let petscii = Petscii::from_char(CHARS[i]);
screen_codes[i] = petscii.to_byte();
i += 1;
}
petscii_bytes
}};
}
#[macro_export]
macro_rules! petscii_codes_null {
($A:expr) => {{
use $crate::petscii_codes;
*const_str::concat_bytes!(petscii_codes!($A), 0u8)
}};
}