factor out ega loader

This commit is contained in:
2016-09-19 03:00:54 -07:00
parent fd9d1cca13
commit 067e8906be
3 changed files with 75 additions and 35 deletions

View File

@@ -1,30 +1,14 @@
extern crate vrtue;
use vrtue::ega;
use vrtue::ega::{Compression, Tiling};
extern crate image; extern crate image;
extern crate itertools;
use std::env; use std::env;
use std::io::Read; use std::io::Read;
use std::path::Path; use std::path::Path;
static EGA_PALETTE: [[u8; 4]; 16] = [[0x00, 0x00, 0x00, 0x00], fn main() {
[0x00, 0x00, 0xAA, 0x00],
[0x00, 0xAA, 0x00, 0x00],
[0x00, 0xAA, 0xAA, 0x00],
[0xAA, 0x00, 0x00, 0x00],
[0xAA, 0x00, 0xAA, 0x00],
[0xAA, 0x55, 0x00, 0x00],
[0xAA, 0xAA, 0xAA, 0x00],
[0x55, 0x55, 0x55, 0x00],
[0x55, 0x55, 0xFF, 0x00],
[0x55, 0xFF, 0x55, 0x00],
[0x55, 0xFF, 0xFF, 0x00],
[0xFF, 0x55, 0x55, 0x00],
[0xFF, 0x55, 0xFF, 0x00],
[0xFF, 0xFF, 0x55, 0x00],
[0xFF, 0xFF, 0xFF, 0x00]];
pub fn main() {
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
let filename; let filename;
if args.len() > 1 { if args.len() > 1 {
@@ -33,24 +17,16 @@ pub fn main() {
filename = "data/SHAPES.EGA"; filename = "data/SHAPES.EGA";
} }
let mut file = std::fs::File::open(Path::new(filename)).unwrap(); let mut file = std::fs::File::open(Path::new(filename))
let mut tile_buf = [0u8; 128]; .expect(&format!("failed opening EGA file: {}", filename));
let mut ega_vec = Vec::<u8>::new();
let mut i = 0; file.read_to_end(&mut ega_vec).expect("Read EGA file");
while file.read_exact(&mut tile_buf).is_ok() { let ega_page = ega::decode(&ega_vec, Compression::UNCOMPRESSED, Tiling::TILED(16));
let tilepixels = tile_buf.iter() for (i, tilepixels) in ega_page.iter().enumerate() {
.flat_map(|tile_byte| {
EGA_PALETTE[(tile_byte >> 4u8 & 0xF) as usize]
.into_iter()
.chain(EGA_PALETTE[(tile_byte & 0xF) as usize]
.into_iter())
})
.map(|x| *x)
.collect::<Vec<u8>>();
let out_name = format!("out/{}.png", i); let out_name = format!("out/{}.png", i);
let out_file = std::fs::File::create(Path::new(&out_name)).expect("open out file"); let out_file = std::fs::File::create(Path::new(&out_name)).expect("open out file");
let enc = image::png::PNGEncoder::new(out_file); let enc = image::png::PNGEncoder::new(out_file);
enc.encode(&tilepixels, 16, 16, image::ColorType::RGBA(8)).expect("write png"); enc.encode(&tilepixels, 16, 16, image::ColorType::RGBA(8)).expect("write png");
i += 1;
} }
} }

61
src/ega.rs Normal file
View File

@@ -0,0 +1,61 @@
static EGA_PALETTE: [[u8; 4]; 16] = [[0x00, 0x00, 0x00, 0x00],
[0x00, 0x00, 0xAA, 0x00],
[0x00, 0xAA, 0x00, 0x00],
[0x00, 0xAA, 0xAA, 0x00],
[0xAA, 0x00, 0x00, 0x00],
[0xAA, 0x00, 0xAA, 0x00],
[0xAA, 0x55, 0x00, 0x00],
[0xAA, 0xAA, 0xAA, 0x00],
[0x55, 0x55, 0x55, 0x00],
[0x55, 0x55, 0xFF, 0x00],
[0x55, 0xFF, 0x55, 0x00],
[0x55, 0xFF, 0xFF, 0x00],
[0xFF, 0x55, 0x55, 0x00],
[0xFF, 0x55, 0xFF, 0x00],
[0xFF, 0xFF, 0x55, 0x00],
[0xFF, 0xFF, 0xFF, 0x00]];
pub enum Compression {
UNCOMPRESSED,
RLE,
LZW
}
pub enum Tiling {
UNTILED,
TILED(u16)
}
pub struct EgaPage {
pub data: Vec<u8>,
pub tilesize: u16,
}
impl EgaPage {
pub fn iter<'a>(&'a self) -> impl Iterator<Item=&'a [u8]> {
self.data.chunks(self.tilesize as usize)
}
}
pub fn decode<'a>(buf: &[u8], compression: Compression, tiling: Tiling)
-> EgaPage {
let out: Vec<u8>;
out = match compression {
Compression::UNCOMPRESSED => buf.iter()
.flat_map(|tile_byte| {
EGA_PALETTE[(tile_byte >> 4u8 & 0xF) as usize]
.into_iter()
.chain(EGA_PALETTE[(tile_byte & 0xF) as usize]
.into_iter())
})
.map(|x| *x)
.collect(),
_ => unimplemented!()
};
let tilesize = match tiling {
Tiling::TILED(tiledim) => 4 * tiledim * tiledim,
Tiling::UNTILED => out.len() as u16
};
EgaPage { data: out, tilesize: tilesize}
}

View File

@@ -1,3 +1,6 @@
#![feature(conservative_impl_trait)]
#[macro_use] extern crate log; #[macro_use] extern crate log;
pub mod ega;
pub mod vr; pub mod vr;