wayfarer/crates/save/src/symbol.rs

99 lines
2.5 KiB
Rust

use core::fmt;
use binrw::{BinRead, BinWrite};
use substring::Substring;
const SYMBOL_PARTS: &str = include_str!("symbol_parts.txt");
const SYMBOL_PART_WIDTH: usize = 6;
const SYMBOL_PART_HEIGTH: usize = 3;
#[derive(Debug, Clone, Copy, BinRead, BinWrite)]
pub struct Symbol {
pub id: u32,
}
impl fmt::Display for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", get_symbol(self.id as usize).unwrap())
}
}
fn get_symbol(id: usize) -> Option<String> {
let (top_left, top_right, btm_left, btm_right) = symbol_part_ids(id)?;
get_symbol_with_parts(top_left, top_right, btm_left, btm_right)
}
fn symbol_part_ids(id: usize) -> Option<(usize, usize, usize, usize)> {
let ids = match id {
0 => (0, 1, 3, 2),
1 => (4, 4, 7, 7),
2 => (9, 9, 13, 2),
3 => (15, 16, 9, 9),
4 => (4, 9, 4, 9),
5 => (15, 12, 3, 9),
6 => (5, 5, 9, 12),
7 => (12, 9, 15, 15),
8 => (7, 9, 12, 8),
9 => (12, 12, 9, 9),
10 => (14, 7, 14, 7),
11 => (8, 8, 13, 13),
12 => (2, 3, 2, 3),
13 => (10, 7, 7, 12),
14 => (7, 7, 10, 12),
15 => (15, 15, 15, 15),
16 => (4, 4, 4, 4),
17 => (11, 10, 11, 10),
18 => (12, 8, 12, 8),
19 => (6, 6, 11, 10),
20 => (12, 9, 11, 10),
_ => return None,
};
Some(ids)
}
fn get_symbol_with_parts(
top_left: usize,
top_right: usize,
btm_left: usize,
btm_right: usize,
) -> Option<String> {
if top_left > 16 || top_right > 16 || btm_left > 16 || btm_right > 16 {
return None;
}
let top_left = get_symbol_part(top_left);
let top_right = get_symbol_part(top_right);
let btm_left = get_symbol_part(btm_left);
let btm_right = get_symbol_part(btm_right);
let top = top_left
.lines()
.zip(top_right.lines())
.map(|(left, right)| format!("{} {}", left, right));
let bottom = btm_left
.lines()
.zip(btm_right.lines())
.map(|(left, right)| format!("{} {}", left, right));
const EMPTY_LINE: &str = " ";
let symbol = top
.chain([EMPTY_LINE.to_string()].into_iter())
.chain(bottom)
.collect::<Vec<_>>()
.join("\n");
Some(symbol)
}
fn get_symbol_part(idx: usize) -> &'static str {
const SYMBOL_PART_SIZE: usize = SYMBOL_PART_WIDTH * SYMBOL_PART_HEIGTH + 2;
let start = (SYMBOL_PART_SIZE + 2) * idx;
let end = start + SYMBOL_PART_SIZE;
SYMBOL_PARTS.substring(start, end)
}