#![warn(missing_docs)]
pub mod color;
use color::Color;
mod ini;
use clap::ArgEnum;
use ini::OptionsIni;
use parse_display::{Display, FromStr};
use serde::de::{self, Deserializer, Unexpected};
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use serde_with::skip_serializing_none;
use std::fmt;
use std::str::FromStr;
use std::u8;
#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Colors {
pub fill_color: Option<Color>,
pub fill_color2: Option<Color>,
pub blend_color: Option<Color>,
pub background_color: Option<Color>,
pub buzz_color: Option<Color>,
pub quiet_color: Option<Color>,
}
impl Default for Colors {
fn default() -> Self {
Self {
fill_color: Some(Color {
r: 255,
g: 255,
b: 255,
}),
fill_color2: Some(Color {
r: 255,
g: 255,
b: 0,
}),
blend_color: Some(Color { r: 255, g: 0, b: 0 }),
background_color: Some(Color { r: 0, g: 0, b: 0 }),
buzz_color: Some(Color { r: 153, g: 0, b: 0 }),
quiet_color: Some(Color { r: 51, g: 0, b: 0 }),
}
}
}
#[derive(Display, FromStr, Debug, PartialEq, Serialize, Deserialize, Copy, Clone, ArgEnum)]
#[serde(rename_all = "lowercase")]
#[display(style = "lowercase")]
#[non_exhaustive]
pub enum Platform {
Octo,
Vip,
Dream6800,
Eti660,
Chip48,
Schip,
XoChip,
}
#[derive(Display, FromStr, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
#[display(style = "lowercase")]
#[non_exhaustive]
pub enum TouchMode {
None,
Swipe,
Seg16,
Seg16Fill,
Gamepad,
Vip,
}
impl Default for TouchMode {
fn default() -> Self {
Self::None
}
}
#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct Quirks {
#[serde(
rename = "shiftQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub shift: Option<bool>,
#[serde(
rename = "loadStoreQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub load_store: Option<bool>,
#[serde(
rename = "jumpQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub jump0: Option<bool>,
#[serde(
rename = "logicQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub logic: Option<bool>,
#[serde(
rename = "clipQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub clip: Option<bool>,
#[serde(
rename = "vBlankQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub vblank: Option<bool>,
#[serde(
rename = "vfOrderQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub vf_order: Option<bool>,
#[serde(rename = "loresDXY0Quirks")]
pub lores_dxy0: Option<LoResDxy0Behavior>,
#[serde(
rename = "resClearQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub res_clear: Option<bool>,
#[serde(
rename = "delayWrapQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub delay_wrap: Option<bool>,
#[serde(
rename = "hiresCollisionQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub hires_collision: Option<bool>,
#[serde(
rename = "clipCollisionQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub clip_collision: Option<bool>,
#[serde(
rename = "scrollQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub scroll: Option<bool>,
#[serde(
rename = "overflowIQuirks",
deserialize_with = "some_bool_from_int",
default
)]
pub overflow_i: Option<bool>,
}
impl Default for Quirks {
fn default() -> Self {
Self {
shift: Some(false),
load_store: Some(false),
jump0: Some(false),
logic: Some(false),
clip: Some(false),
vblank: Some(false),
vf_order: Some(false),
lores_dxy0: Some(LoResDxy0Behavior::default()),
res_clear: Some(true),
delay_wrap: Some(false),
hires_collision: Some(false),
clip_collision: Some(false),
scroll: Some(false),
overflow_i: Some(false),
}
}
}
#[derive(Display, FromStr, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[display(style = "snake_case")]
pub enum LoResDxy0Behavior {
NoOp,
TallSprite,
BigSprite,
}
impl Default for LoResDxy0Behavior {
fn default() -> Self {
Self::BigSprite
}
}
#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct Options {
#[serde(default, deserialize_with = "some_u16_from_int_or_str")]
pub tickrate: Option<u16>,
#[serde(default, deserialize_with = "some_u16_from_int_or_str")]
pub max_size: Option<u16>, #[serde(default)]
pub screen_rotation: ScreenRotation,
#[serde(default)]
pub font_style: Font,
#[serde(default)]
pub touch_input_mode: TouchMode, #[serde(default, deserialize_with = "some_u16_from_int_or_str")]
pub start_address: Option<u16>,
#[serde(flatten)]
pub colors: Colors,
#[serde(flatten)]
pub quirks: Quirks,
}
impl Default for Options {
fn default() -> Self {
Self {
tickrate: Some(500),
max_size: Some(65024),
screen_rotation: ScreenRotation::default(),
font_style: Font::default(),
touch_input_mode: TouchMode::default(),
start_address: Some(0x200),
colors: Colors::default(),
quirks: Quirks::default(),
}
}
}
#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u16)]
pub enum ScreenRotation {
Normal = 0,
ClockWise = 90,
UpsideDown = 180,
CounterClockWise = 270,
}
impl Default for ScreenRotation {
fn default() -> Self {
Self::Normal
}
}
impl FromStr for Options {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
impl Options {
pub fn from_ini(s: &str) -> Result<Self, serde_ini::de::Error> {
Ok(Self::from(OptionsIni::from_str(s)?))
}
pub fn to_ini(self) -> String {
OptionsIni::to_string(&OptionsIni::from(self))
}
pub fn new(platform: Platform) -> Self {
match platform {
Platform::Octo => Self::default(),
Platform::XoChip => Options {
max_size: Some(65024),
..Self::default()
},
Platform::Vip => Self {
tickrate: Some(20),
max_size: Some(3216),
screen_rotation: ScreenRotation::Normal,
font_style: Font::Vip,
touch_input_mode: TouchMode::None,
start_address: Some(0x200),
colors: Colors::default(),
quirks: Quirks {
shift: Some(false),
load_store: Some(false),
jump0: Some(false),
logic: Some(true),
clip: Some(true),
vblank: Some(true),
vf_order: Some(true),
delay_wrap: Some(false),
overflow_i: Some(false),
lores_dxy0: Some(LoResDxy0Behavior::NoOp),
hires_collision: None,
clip_collision: None,
scroll: None,
res_clear: None,
},
},
Platform::Dream6800 => Self {
tickrate: Some(20),
max_size: Some(3216), screen_rotation: ScreenRotation::Normal,
font_style: Font::Dream6800,
touch_input_mode: TouchMode::None,
start_address: Some(0x200),
colors: Colors::default(),
quirks: Quirks {
shift: Some(false),
load_store: Some(false),
jump0: Some(false),
logic: Some(true),
clip: Some(true),
vblank: Some(true),
vf_order: Some(true),
delay_wrap: Some(true),
overflow_i: Some(false),
lores_dxy0: Some(LoResDxy0Behavior::TallSprite),
hires_collision: None,
clip_collision: None,
scroll: None,
res_clear: None,
},
},
Platform::Eti660 => Self {
tickrate: Some(20),
max_size: Some(3216), screen_rotation: ScreenRotation::Normal,
font_style: Font::Eti660,
touch_input_mode: TouchMode::None,
start_address: Some(0x600),
colors: Colors::default(),
quirks: Quirks {
shift: Some(false),
load_store: Some(false),
jump0: Some(false),
logic: Some(true),
clip: Some(true),
vblank: Some(true),
vf_order: Some(true),
delay_wrap: Some(false),
overflow_i: Some(false),
lores_dxy0: Some(LoResDxy0Behavior::NoOp),
hires_collision: None,
clip_collision: None,
scroll: None,
res_clear: None,
},
},
Platform::Chip48 => Self {
tickrate: Some(40),
max_size: Some(3583), screen_rotation: ScreenRotation::Normal,
font_style: Font::Schip, touch_input_mode: TouchMode::None,
start_address: Some(0x200),
colors: Colors::default(), quirks: Quirks {
shift: Some(true),
load_store: Some(true),
jump0: Some(true),
logic: Some(false),
clip: Some(true),
vblank: Some(false),
vf_order: None,
delay_wrap: Some(false),
overflow_i: Some(false),
lores_dxy0: Some(LoResDxy0Behavior::TallSprite), res_clear: None,
hires_collision: None,
clip_collision: None,
scroll: None,
},
},
Platform::Schip => Self {
tickrate: Some(40),
max_size: Some(3583),
screen_rotation: ScreenRotation::Normal,
font_style: Font::Schip,
touch_input_mode: TouchMode::None,
start_address: Some(0x200),
colors: Colors::default(), quirks: Quirks {
shift: Some(true),
load_store: Some(true),
jump0: Some(true),
logic: Some(false),
clip: Some(true),
vblank: Some(false),
vf_order: None, res_clear: Some(false),
delay_wrap: Some(false),
overflow_i: Some(false),
lores_dxy0: Some(LoResDxy0Behavior::TallSprite),
hires_collision: Some(true),
clip_collision: Some(true),
scroll: Some(true),
},
},
}
}
}
impl fmt::Display for Options {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match serde_json::to_string(self) {
Ok(string) => write!(f, "{}", string),
_ => Err(fmt::Error),
}
}
}
fn some_u16_from_int_or_str<'de, D>(deserializer: D) -> Result<Option<u16>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum U16OrStr<'a> {
U16(u16),
Str(&'a str),
}
Ok(match U16OrStr::deserialize(deserializer)? {
U16OrStr::Str(v) => match v.parse() {
Ok(v) => Some(v),
Err(_) => None,
},
U16OrStr::U16(v) => Some(v),
})
}
fn some_bool_from_int<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum BoolOrU8 {
Bool(bool),
U8(u8),
}
match BoolOrU8::deserialize(deserializer)? {
BoolOrU8::Bool(v) => Ok(Some(v)),
BoolOrU8::U8(1) => Ok(Some(true)),
BoolOrU8::U8(0) => Ok(Some(false)),
BoolOrU8::U8(other) => Err(de::Error::invalid_value(
Unexpected::Unsigned(u64::from(other)),
&"zero or one",
)),
}
}
#[derive(Display, FromStr, Debug, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum Font {
#[serde(rename = "octo")]
#[display("octo")]
Octo,
#[serde(rename = "vip")]
#[display("vip")]
Vip,
#[serde(rename = "dream_6800")]
#[display("dream_6800")]
Dream6800,
#[serde(rename = "eti_660")]
#[display("eti_660")]
Eti660,
#[serde(rename = "schip")]
#[display("schip")]
Schip,
#[serde(rename = "fish")]
#[display("fish")]
Fish,
#[serde(rename = "akouz1")]
#[display("akouz1")]
AKouZ1,
}
impl Default for Font {
fn default() -> Self {
Self::Octo
}
}
impl Font {
pub fn get_font_data(&self) -> ([u8; 5 * 16], Option<Vec<u8>>) {
match self {
Font::Octo => (
[
0xF0, 0x90, 0x90, 0x90, 0xF0, 0x20, 0x60, 0x20, 0x20, 0x70, 0xF0, 0x10, 0xF0, 0x80, 0xF0, 0xF0, 0x10, 0xF0, 0x10, 0xF0, 0x90, 0x90, 0xF0, 0x10, 0x10, 0xF0, 0x80, 0xF0, 0x10, 0xF0, 0xF0, 0x80, 0xF0, 0x90, 0xF0, 0xF0, 0x10, 0x20, 0x40, 0x40, 0xF0, 0x90, 0xF0, 0x90, 0xF0, 0xF0, 0x90, 0xF0, 0x10, 0xF0, 0xF0, 0x90, 0xF0, 0x90, 0x90, 0xE0, 0x90, 0xE0, 0x90, 0xE0, 0xF0, 0x80, 0x80, 0x80, 0xF0, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0xF0, 0x80, 0xF0, 0x80, 0xF0, 0xF0, 0x80, 0xF0, 0x80, 0x80, ],
Some(vec![
0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0x18, 0x78, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x06, 0x0C, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF, 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xFC, 0xFC, 0xC3, 0xC3, 0xFC, 0xFC, 0xC3, 0xC3, 0xFC, 0xFC, 0x3C, 0xFF, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0xFF, 0x3C, 0xFC, 0xFE, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFE, 0xFC, 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, ]),
),
Font::Vip => (
[
0xF0, 0x90, 0x90, 0x90, 0xF0, 0x60, 0x20, 0x20, 0x20, 0x70, 0xF0, 0x10, 0xF0, 0x80, 0xF0, 0xF0, 0x10, 0xF0, 0x10, 0xF0, 0xA0, 0xA0, 0xF0, 0x20, 0x20, 0xF0, 0x80, 0xF0, 0x10, 0xF0, 0xF0, 0x80, 0xF0, 0x90, 0xF0, 0xF0, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x90, 0xF0, 0x90, 0xF0, 0xF0, 0x90, 0xF0, 0x10, 0xF0, 0xF0, 0x90, 0xF0, 0x90, 0x90, 0xF0, 0x50, 0x70, 0x50, 0xF0, 0xF0, 0x80, 0x80, 0x80, 0xF0, 0xF0, 0x50, 0x50, 0x50, 0xF0, 0xF0, 0x80, 0xF0, 0x80, 0xF0, 0xF0, 0x80, 0xF0, 0x80, 0x80, ],
None,
),
Font::Dream6800 => (
[
0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x20, 0xE0, 0x80, 0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0x80, 0xA0, 0xA0, 0xE0, 0x20, 0xE0, 0x80, 0xE0, 0x20, 0xE0, 0xE0, 0x80, 0xE0, 0xA0, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0xE0, 0xA0, 0xE0, 0xA0, 0xE0, 0xE0, 0xA0, 0xE0, 0x20, 0xE0, 0xE0, 0xA0, 0xE0, 0xA0, 0xA0, 0xC0, 0xA0, 0xE0, 0xA0, 0xC0, 0xE0, 0x80, 0x80, 0x80, 0xE0, 0xC0, 0xA0, 0xA0, 0xA0, 0xC0, 0xE0, 0x80, 0xE0, 0x80, 0xE0, 0xE0, 0x80, 0xC0, 0x80, 0x80, ],
None,
),
Font::Eti660 => (
[
0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xE0, 0x20, 0xE0, 0x80, 0xE0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0xE0, 0x80, 0xE0, 0x20, 0xE0, 0xE0, 0x80, 0xE0, 0xA0, 0xE0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0xE0, 0xA0, 0xE0, 0xA0, 0xE0, 0xE0, 0xA0, 0xE0, 0x20, 0xE0, 0xE0, 0xA0, 0xE0, 0xA0, 0xA0, 0x80, 0x80, 0xE0, 0xA0, 0xE0, 0xE0, 0x80, 0x80, 0x80, 0xE0, 0x20, 0x20, 0xE0, 0xA0, 0xE0, 0xE0, 0x80, 0xE0, 0x80, 0xE0, 0xE0, 0x80, 0xC0, 0x80, 0x80, ],
None,
),
Font::Schip => (
[
0xF0, 0x90, 0x90, 0x90, 0xF0, 0x20, 0x60, 0x20, 0x20, 0x70, 0xF0, 0x10, 0xF0, 0x80, 0xF0, 0xF0, 0x10, 0xF0, 0x10, 0xF0, 0x90, 0x90, 0xF0, 0x10, 0x10, 0xF0, 0x80, 0xF0, 0x10, 0xF0, 0xF0, 0x80, 0xF0, 0x90, 0xF0, 0xF0, 0x10, 0x20, 0x40, 0x40, 0xF0, 0x90, 0xF0, 0x90, 0xF0, 0xF0, 0x90, 0xF0, 0x10, 0xF0, 0xF0, 0x90, 0xF0, 0x90, 0x90, 0xE0, 0x90, 0xE0, 0x90, 0xE0, 0xF0, 0x80, 0x80, 0x80, 0xF0, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0xF0, 0x80, 0xF0, 0x80, 0xF0, 0xF0, 0x80, 0xF0, 0x80, 0x80, ],
Some(vec![
0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C, 0x18, 0x38, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x3E, 0x7F, 0xC3, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xFF, 0xFF, 0x3C, 0x7E, 0xC3, 0x03, 0x0E, 0x0E, 0x03, 0xC3, 0x7E, 0x3C, 0x06, 0x0E, 0x1E, 0x36, 0x66, 0xC6, 0xFF, 0xFF, 0x06, 0x06, 0xFF, 0xFF, 0xC0, 0xC0, 0xFC, 0xFE, 0x03, 0xC3, 0x7E, 0x3C, 0x3E, 0x7C, 0xE0, 0xC0, 0xFC, 0xFE, 0xC3, 0xC3, 0x7E, 0x3C, 0xFF, 0xFF, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x60, 0x60, 0x3C, 0x7E, 0xC3, 0xC3, 0x7E, 0x7E, 0xC3, 0xC3, 0x7E, 0x3C, 0x3C, 0x7E, 0xC3, 0xC3, 0x7F, 0x3F, 0x03, 0x03, 0x3E, 0x7C, ]),
),
Font::Fish => (
[
0x60, 0xA0, 0xA0, 0xA0, 0xC0, 0x40, 0xC0, 0x40, 0x40, 0xE0, 0xC0, 0x20, 0x40, 0x80, 0xE0, 0xC0, 0x20, 0x40, 0x20, 0xC0, 0x20, 0xA0, 0xE0, 0x20, 0x20, 0xE0, 0x80, 0xC0, 0x20, 0xC0, 0x40, 0x80, 0xC0, 0xA0, 0x40, 0xE0, 0x20, 0x60, 0x40, 0x40, 0x40, 0xA0, 0x40, 0xA0, 0x40, 0x40, 0xA0, 0x60, 0x20, 0x40, 0x40, 0xA0, 0xE0, 0xA0, 0xA0, 0xC0, 0xA0, 0xC0, 0xA0, 0xC0, 0x60, 0x80, 0x80, 0x80, 0x60, 0xC0, 0xA0, 0xA0, 0xA0, 0xC0, 0xE0, 0x80, 0xC0, 0x80, 0xE0, 0xE0, 0x80, 0xC0, 0x80, 0x80, ],
Some(vec![
0x7C, 0xC6, 0xCE, 0xDE, 0xD6, 0xF6, 0xE6, 0xC6, 0x7C, 0x00, 0x10, 0x30, 0xF0, 0x30, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, 0x78, 0xCC, 0xCC, 0x0C, 0x18, 0x30, 0x60, 0xCC, 0xFC, 0x00, 0x78, 0xCC, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0xCC, 0x78, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x0C, 0x1E, 0x00, 0xFC, 0xC0, 0xC0, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xF8, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0xFE, 0xC6, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xCC, 0xEC, 0x78, 0xDC, 0xCC, 0xCC, 0x78, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x18, 0x18, 0x30, 0x70, 0x00, 0x30, 0x78, 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x3C, 0x66, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x66, 0x3C, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0xFE, 0x62, 0x60, 0x64, 0x7C, 0x64, 0x60, 0x62, 0xFE, 0x00, 0xFE, 0x66, 0x62, 0x64, 0x7C, 0x64, 0x60, 0x60, 0xF0, 0x00, ]),
),
Font::AKouZ1 => (
[
0x60, 0x90, 0x90, 0x90, 0x60, 0x20, 0x60, 0x20, 0x20, 0x70, 0xE0, 0x10, 0x60, 0x80, 0xF0, 0xE0, 0x10, 0xE0, 0x10, 0xE0, 0x30, 0x50, 0x90, 0xF0, 0x10, 0xF0, 0x80, 0xF0, 0x10, 0xE0, 0x70, 0x80, 0xF0, 0x90, 0x60, 0xF0, 0x10, 0x20, 0x40, 0x40, 0x60, 0x90, 0x60, 0x90, 0x60, 0x60, 0x90, 0x70, 0x10, 0x60, 0x60, 0x90, 0xF0, 0x90, 0x90, 0xE0, 0x90, 0xE0, 0x90, 0xE0, 0x70, 0x80, 0x80, 0x80, 0x70, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0xF0, 0x80, 0xE0, 0x80, 0xF0, 0xF0, 0x80, 0xE0, 0x80, 0x80, ],
Some(vec![
0x7E, 0xC7, 0xC7, 0xCB, 0xCB, 0xD3, 0xD3, 0xE3, 0xE3, 0x7E, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x7E, 0xC3, 0x03, 0x03, 0x0E, 0x18, 0x30, 0x60, 0xC0, 0xFF, 0x7E, 0xC3, 0x03, 0x03, 0x1E, 0x03, 0x03, 0x03, 0xC3, 0x7E, 0x06, 0x0E, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFF, 0x06, 0x06, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE, 0x03, 0x03, 0x03, 0xC3, 0x7E, 0x7E, 0xC3, 0xC0, 0xC0, 0xFE, 0xC3, 0xC3, 0xC3, 0xC3, 0x7E, 0xFF, 0x03, 0x03, 0x03, 0x06, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x7E, 0xC3, 0xC3, 0xC3, 0x7E, 0xC3, 0xC3, 0xC3, 0xC3, 0x7E, 0x7E, 0xC3, 0xC3, 0xC3, 0x7F, 0x03, 0x03, 0x03, 0xC3, 0x7E, 0x7E, 0xC3, 0xC3, 0xC3, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFE, 0xC3, 0xC3, 0xC3, 0xFE, 0xC3, 0xC3, 0xC3, 0xC3, 0xFE, 0x7E, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x7E, 0xFC, 0xC6, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC6, 0xFC, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, ]),
),
}
}
}