1use std::collections::HashMap;
4use std::fs::File;
5use std::io::{Error, Read};
6
7use mem_read::*;
8
9use image::{ImageBuffer};
10use rayon::prelude::*;
11
12use draw::*;
13
14const SPRITE_DATA_SIZE: u32 = 32 * 32 * 4;
15
16pub struct SpriteData {
17 pub version: u32,
18 pub sprites: HashMap<u32, Image>,
19}
20
21impl SpriteData {
22 pub fn get_image(&self, id: u32) -> Option<&Image> {
23 self.sprites.get(&id)
24 }
25}
26
27pub fn parse(filename: String) -> Result<SpriteData, Error> {
28 let mut file = File::open(filename)?;
29 let mut data: Vec<u8> = Vec::new();
30 file.read_to_end(&mut data)?;
31 let data: &mut &[u8] = &mut data.as_ref();
32 let begin = data.clone();
33
34 let version = data.get()?;
35
36 let count = data.get::<u32>()?;
37 let mut vec = Vec::with_capacity(count as _);
38 vec.extend((0..count).flat_map(|id| {
39 data.get::<u32>()
40 .ok()
41 .and_then(|x| if x == 0 { None } else { Some((id + 1, x)) })
42 }));
43
44 Ok(SpriteData {
45 version,
46 sprites: vec
47 .into_par_iter()
48 .map(|n| {
49 let data: &mut &[u8] = &mut &begin[n.1 as _..];
50 let mut img: Image = ImageBuffer::new(32, 32);
51
52 let color_key = data.get::<[u8; 3]>()?;
53 let size = data.get()?;
54
55 let mut write = 0;
56 let mut read = 0;
57 let mut i = 0;
58 while read < size && write < SPRITE_DATA_SIZE {
59 let transparent_count = data.get::<u16>()?;
60 let colored_count = data.get::<u16>()?;
61
62 for _ in 0..transparent_count {
63 img.get_pixel_mut(i / 32, i % 32).data = [0, 0, 0, 0];
64 i += 1;
65 }
66
67 for _ in 0..colored_count {
68 let (r, g, b, a) = (data.get()?, data.get()?, data.get()?, 0); img.get_pixel_mut(i / 32, i % 32).data = [r, g, b, a];
70 i += 1;
71 }
72
73 write += 4 * transparent_count as u32 + 4 * colored_count as u32;
74 read += 4 + (3 * colored_count);
75 }
76
77 Ok((n.0, img))
80 })
81 .collect::<Result<_, Error>>()?,
82 })
83}