maikor_vm_file/
game_file.rs

1use crate::constants::mem::*;
2use crate::file_utils::{convert_vec, read_sized_blocks, ReaderExt};
3use crate::read_write_impl::{Readable, Writeable};
4use crate::GameFileError::FileAccessError;
5use crate::{GameFile, GameFileError, GameFileHeader};
6
7impl GameFile {
8    pub fn new(
9        header: GameFileHeader,
10        main_code: [u8; MAIN_CODE],
11        code_banks: Vec<[u8; CODE_BANK]>,
12        atlases: Vec<[u8; ATLAS_BANK]>,
13    ) -> Self {
14        Self {
15            header,
16            main_code,
17            code_banks,
18            atlases,
19        }
20    }
21}
22
23impl Readable for GameFile {
24    fn from_reader<R: ReaderExt>(reader: &mut R) -> Result<GameFile, GameFileError> {
25        let header = GameFileHeader::from_reader(reader)?;
26        let main_code = reader
27            .read_block(CODE_BANK)
28            .map_err(|e| FileAccessError(e, "reading main code"))?;
29        let code_banks = read_sized_blocks(reader, header.code_bank_count as usize)?;
30        let atlas_banks = read_sized_blocks(reader, header.atlas_bank_count as usize)?;
31        Ok(GameFile::new(
32            header,
33            convert_vec(main_code),
34            code_banks,
35            atlas_banks,
36        ))
37    }
38}
39
40impl Writeable for GameFile {
41    fn as_bytes(&self) -> Result<Vec<u8>, GameFileError> {
42        let mut output = self.header.as_bytes()?;
43        output.extend_from_slice(&self.main_code);
44        for bank in &self.code_banks {
45            output.extend_from_slice(bank);
46        }
47        for bank in &self.atlases {
48            output.extend_from_slice(bank);
49        }
50
51        Ok(output)
52    }
53}
54
55#[cfg(test)]
56mod test {
57    use crate::read_write_impl::Writeable;
58    use crate::{GameFile, GameFileHeader, ATLAS_BANK, CODE_BANK, MAIN_CODE};
59
60    #[test]
61    #[rustfmt::skip]
62    fn test_write() {
63        let header = GameFileHeader::new(String::from("1"), 1, 1, 1,0, String::from("a"), String::from("b"), String::from("c"), 1, 1);
64        let file = GameFile::new(header, [1; MAIN_CODE], vec![[2; CODE_BANK]], vec![[3; ATLAS_BANK]]);
65        
66        let bytes  = file.as_bytes().unwrap();
67        assert_eq!(bytes.len(), MAIN_CODE + CODE_BANK + ATLAS_BANK + 22);
68    }
69}