maikor_vm_file/
atlas_file.rs1use crate::file_utils::ReaderExt;
2use crate::read_write_impl::{Readable, Writeable};
3use crate::GameFileError;
4use crate::GameFileError::InvalidAtlas;
5use maikor_platform::constants::{ATLAS_TILE_HEIGHT, ATLAS_TILE_WIDTH};
6
7const ATLAS_SPRITE_SIZE: usize = ATLAS_TILE_HEIGHT * ATLAS_TILE_WIDTH;
8
9pub struct AtlasFile {
10 images: Vec<[u8; ATLAS_SPRITE_SIZE]>,
11}
12
13impl AtlasFile {
14 pub fn validate(&self) -> Result<(), Vec<String>> {
15 let mut error = vec![];
16 if self.images.len() > ATLAS_SPRITE_SIZE {
17 error.push(String::from("Atlas has too many images"));
18 }
19 if error.is_empty() {
20 Ok(())
21 } else {
22 Err(error)
23 }
24 }
25}
26
27impl Writeable for AtlasFile {
28 fn as_bytes(&self) -> Result<Vec<u8>, GameFileError> {
29 let mut output = vec![];
30 for image in &self.images {
31 output.extend_from_slice(image);
32 }
33 Ok(output)
34 }
35}
36
37impl Readable for AtlasFile {
38 fn from_reader<R: ReaderExt>(reader: &mut R) -> Result<Self, GameFileError>
39 where
40 Self: Sized,
41 {
42 let mut bytes = vec![];
43 let read_count = reader
44 .read_to_end(&mut bytes)
45 .map_err(|e| InvalidAtlas(e.to_string()))?;
46 if read_count as f64 % ATLAS_SPRITE_SIZE as f64 != 0.0 {
47 return Err(InvalidAtlas(format!(
48 "Content must be multiple of {}",
49 ATLAS_SPRITE_SIZE
50 )));
51 }
52 let mut images = vec![];
53 for chunk in bytes.chunks_exact_mut(ATLAS_SPRITE_SIZE) {
54 let mut image = [0; ATLAS_SPRITE_SIZE];
55 unsafe {
56 std::ptr::copy_nonoverlapping(
57 chunk.as_mut_ptr(),
58 image.as_mut_ptr(),
59 ATLAS_SPRITE_SIZE,
60 );
61 }
62 images.push(image);
63 }
64 Ok(AtlasFile { images })
65 }
66}
67
68#[cfg(test)]
69mod test {
70 use crate::atlas_file::AtlasFile;
71 use crate::read_write_impl::{Readable, Writeable};
72 use std::io::BufReader;
73
74 #[test]
75 fn basic_read_write() {
76 let image = [
77 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
78 24, 25, 26, 27, 28, 29, 30, 31,
79 ];
80 let atlas = AtlasFile {
81 images: vec![image],
82 };
83 let output = atlas.as_bytes().unwrap();
84 assert_eq!(image.to_vec(), output);
85 let parsed_atlas = AtlasFile::from_reader(&mut BufReader::new(&*image.to_vec())).unwrap();
86 assert_eq!(parsed_atlas.images.len(), 1);
87 let mut bytes = image.to_vec();
88 bytes.extend_from_slice(&image);
89 let parsed_atlas = AtlasFile::from_reader(&mut BufReader::new(&*bytes)).unwrap();
90 assert_eq!(parsed_atlas.images.len(), 2);
91 assert_eq!(parsed_atlas.images[1], image);
92 }
93}