factor out ega loader
This commit is contained in:
@@ -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
61
src/ega.rs
Normal 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}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user