use std::path::PathBuf;
use crate::binaryreader::*;
#[derive(Debug)]
pub struct AtlasMeta {
pub header: String,
pub data: PathBuf,
pub sprites: Vec<Sprite>,
}
#[derive(Debug, Clone)]
pub struct Sprite {
pub path: String,
pub x: i16,
pub y: i16,
pub w: i16,
pub h: i16,
pub offset_x: i16,
pub offset_y: i16,
pub real_w: i16,
pub real_h: i16,
}
pub fn decode_atlas(buffer: &[u8]) -> Result<Vec<AtlasMeta>> {
let (_, buffer) = read_i32(buffer)?;
let (header, buffer) = read_string(buffer)?;
let (_, buffer) = read_i32(buffer)?;
let (count, mut buffer) = read_u16(buffer)?;
let mut banks = Vec::with_capacity(count as usize);
for _ in 0..banks.capacity() {
let data_file;
let n_sprites;
(data_file, buffer) = read_string(buffer)?;
(n_sprites, buffer) = read_i16(buffer)?;
let mut sprites = Vec::with_capacity(n_sprites as usize);
for _ in 0..n_sprites {
let path_raw;
(path_raw, buffer) = read_string(buffer)?;
let path = path_raw.replace('\\', "/");
let x = read_i16_mut(&mut buffer)?;
let y = read_i16_mut(&mut buffer)?;
let w = read_i16_mut(&mut buffer)?;
let h = read_i16_mut(&mut buffer)?;
let offset_x = read_i16_mut(&mut buffer)?;
let offset_y = read_i16_mut(&mut buffer)?;
let real_w = read_i16_mut(&mut buffer)?;
let real_h = read_i16_mut(&mut buffer)?;
sprites.push(Sprite {
path,
x,
y,
w,
h,
offset_x,
offset_y,
real_w,
real_h,
})
}
banks.push(AtlasMeta {
header: header.to_owned(),
data: PathBuf::from(data_file),
sprites,
});
}
Ok(banks)
}
pub fn decode_data(data: &[u8]) -> Result<(u32, u32, Vec<u8>), Error> {
let (width, data) = read_u32(data)?;
let (height, data) = read_u32(data)?;
let (has_alpha, mut data) = read_bool(data)?;
let mut buf: Vec<u8> = Vec::with_capacity((width * height * 4) as usize);
while let Some((&run_length, remaining)) = data.split_first() {
data = remaining;
let color = if has_alpha {
let a;
(a, data) = data.split_first().unwrap();
let [b, g, r] = match a {
0 => [0, 0, 0],
_ => {
let color;
(color, data) = data.split_at(3);
color.try_into().unwrap()
}
};
[r, g, b, *a]
} else {
let color;
(color, data) = data.split_at(3);
let [b, g, r] = color.try_into().unwrap();
[r, g, b, 255]
};
for _ in 0..run_length {
buf.extend(color);
}
}
Ok((width, height, buf))
}