ot/
spr.rs

1// https://github.com/edubart/otclient/blob/e870110875627d55006236b7e4996f28fed9a287/src/client/spritemanager.cpp
2
3use 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); // TODO: , 0)?
69                        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 /* channels */ * colored_count);
75                }
76
77                //img.save(format!("sprites/{}.png", n.0))?;
78
79                Ok((n.0, img))
80            })
81            .collect::<Result<_, Error>>()?,
82    })
83}