Actually parse bdf directly, emit rom to be used for george-emu
This commit is contained in:
+51
-45
@@ -1,58 +1,64 @@
|
||||
#![allow(clippy::println_empty_string)]
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{self, Write},
|
||||
path::PathBuf,
|
||||
io::{Read, Write},
|
||||
ops::Neg,
|
||||
u8,
|
||||
};
|
||||
|
||||
extern crate png;
|
||||
|
||||
const MAX_ROWS: usize = 13;
|
||||
const MAX_CHARS: u16 = 0x100; // Non inclusive, first char is 0x00
|
||||
|
||||
fn to_bitmap(path: &str, max_chars: u16, max_rows: usize) -> Result<Vec<u8>, io::Error> {
|
||||
let decoder = png::Decoder::new(File::open(path)?);
|
||||
let mut reader = decoder.read_info()?;
|
||||
let mut buf = vec![0; reader.output_buffer_size()];
|
||||
let info = reader.next_frame(&mut buf)?;
|
||||
let bytes = &buf[..info.buffer_size()];
|
||||
let compressed: Vec<u8> = bytes.iter().step_by(4).cloned().collect(); // We're not using color, so we skip duplicate color components
|
||||
let mut finalbuf = Vec::new();
|
||||
for (i, _bit) in compressed.iter().step_by(8).enumerate() {
|
||||
let mut byte = 0u8;
|
||||
for j in (0..8).rev() {
|
||||
if compressed[i * 8 + j] == 255 {
|
||||
byte |= 0x80 >> j;
|
||||
}
|
||||
}
|
||||
finalbuf.push(byte);
|
||||
// takes all charaters in bdf and returns a vec of each character row byte in order, normalized to
|
||||
// width & height of the font (only works with 8 or fewer pixel wide fonts, should work for any height)
|
||||
fn bdf_to_vec(path: &str) -> Vec<u8> {
|
||||
let mut bdf_vec = Vec::new();
|
||||
let file = File::open(path).unwrap();
|
||||
let mut bdf_font_bytes = Vec::new();
|
||||
for byte in file.bytes() {
|
||||
bdf_font_bytes.push(byte.unwrap());
|
||||
}
|
||||
Ok(finalbuf)
|
||||
}
|
||||
let bdf_font = bdf_parser::BdfFont::parse(&bdf_font_bytes).unwrap();
|
||||
for glyph in bdf_font.glyphs.iter() {
|
||||
let glyph_offset_x = glyph.bounding_box.offset.x;
|
||||
let glyph_offset_y = glyph.bounding_box.offset.y;
|
||||
let glyph_height = glyph.bounding_box.size.y;
|
||||
let font_height = bdf_font.metadata.bounding_box.size.y;
|
||||
let font_offset_y = bdf_font.metadata.bounding_box.offset.y;
|
||||
|
||||
fn reorder_bitmap(bitmap: &[u8]) -> Vec<u8> {
|
||||
let mut reordered: Vec<u8> = Vec::new();
|
||||
for row in 0..MAX_ROWS {
|
||||
for character in 0x00..MAX_CHARS {
|
||||
let mut byte = 0u8;
|
||||
for i in 0..8 {
|
||||
// character number + row offset & bitmask = pixel
|
||||
if bitmap[character as usize + (row * 0xFF)] & 0x80 >> i > 0 {
|
||||
byte |= 0x80 >> i;
|
||||
}
|
||||
}
|
||||
reordered.push(byte);
|
||||
let top_space = font_height + font_offset_y - glyph_height - glyph_offset_y;
|
||||
for _i in 0..top_space {
|
||||
bdf_vec.push(0x00);
|
||||
}
|
||||
for bitmap in glyph.bitmap.iter() {
|
||||
bdf_vec.push(bitmap >> glyph_offset_x);
|
||||
}
|
||||
|
||||
let bottom_space = font_offset_y.neg() + glyph_offset_y;
|
||||
for _i in 0..bottom_space {
|
||||
bdf_vec.push(0x00);
|
||||
}
|
||||
}
|
||||
reordered
|
||||
bdf_vec
|
||||
}
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let compressed = to_bitmap("./cozette.png", MAX_CHARS, MAX_ROWS)?;
|
||||
let reordered = reorder_bitmap(&compressed);
|
||||
let mut outfile = File::create("./cozette.bin")?;
|
||||
outfile.set_len(0xFFFF)?;
|
||||
outfile.write_all(&reordered)?;
|
||||
Ok(())
|
||||
// takes an vec of ordered characters and translates them for use with the character rom
|
||||
// TODO: make this work for any arbitrary char rom pin format using some kinda interface
|
||||
fn reorder_bitmap(bitmap: &[u8], font_height: usize) -> Vec<u8> {
|
||||
let mut rom = vec![0; 0x8000]; // create vec the size of character rom
|
||||
|
||||
for row in 0..font_height {
|
||||
for ascii_address in 0..u8::MAX {
|
||||
// first 8 bits of address pick character
|
||||
// next 5 bits pick row, and TODO: final 2 pick character set
|
||||
let byte = bitmap[ascii_address as usize * font_height + row];
|
||||
let rom_index: u16 = ((row as u16) << 8) + ascii_address as u16;
|
||||
rom[rom_index as usize] = byte;
|
||||
}
|
||||
}
|
||||
rom
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let bits = bdf_to_vec("Cozette8-13.bdf");
|
||||
let mut rom = File::create("./cozette.rom").unwrap();
|
||||
let reordered = reorder_bitmap(&bits, 13);
|
||||
rom.write_all(&reordered).unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user