1pub mod atlas_file;
2mod constants;
3mod file_utils;
4pub mod game_file;
5pub mod game_header;
6pub mod manifest;
7pub mod palette;
8pub mod read_write_impl;
9
10use crate::constants::mem::*;
11use crate::GameFileError::{FileFormatInvalid, InvalidFileVersion};
12use std::fmt::Debug;
13use std::io;
14use thiserror::Error;
15
16const ID_HEADER: [u8; 2] = [0xFD, 0xA1];
17const MAIKOR_HEADER_LENGTH: usize = 16;
18const FILE_FORMAT_VER: u8 = 1;
19const MAX_STRING_LEN: usize = 255;
20const MIN_FILE_SIZE: u64 = MAIKOR_HEADER_LENGTH as u64 + MAIN_CODE as u64 + 3;
21const MAX_FILE_SIZE: u64 = ATLAS_BANK as u64 * 255 + CODE_BANK as u64 * 255 + MIN_FILE_SIZE;
22
23#[derive(Error, Debug)]
24pub enum GameFileError {
25 #[error("Maikor file not found")]
26 FileNotFound(),
27 #[error("Maikor file read error, not a file/can't access")]
28 NotAFile(),
29 #[error("Maikor read access error, for field {1}: {0}")]
30 FileAccessError(#[source] io::Error, &'static str),
31 #[error("Maikor file too large. File was {0}, max is {MAX_FILE_SIZE}")]
32 FileTooLarge(u64),
33 #[error("Maikor file too small. This may be not be a valid Maikor file.")]
34 FileTooSmall(),
35 #[error("Not a Maikor game file")]
36 FileFormatInvalid(),
37 #[error("Unsupported Maikor game file version, was {0} and must be {FILE_FORMAT_VER}")]
38 InvalidFileVersion(u8),
39 #[error("Invalid/corrupt Maikor file")]
40 InvalidMaikorFile(),
41 #[error("Invalid atlas banks")]
42 InvalidAtlasBanks(),
43 #[error("Header validation failed:\n{0}")]
44 InvalidHeader(&'static str),
45 #[error("{0} field is too long, max is {1} and was {2}")]
46 FieldTooLong(&'static str, usize, usize),
47 #[error("Invalid Atlas file: {0}")]
48 InvalidAtlas(String),
49 #[error("Error parsing manifest: {0}")]
50 ManifestParsingError(String),
51 #[error("Invalid Palette file: {0}")]
52 InvalidPalette(String),
53}
54
55#[derive(Debug, Eq, PartialEq)]
56pub struct GameFileHeader {
57 pub id: String,
59 pub build: u32,
61 pub compiled_for_maikor_version: u16,
63 pub min_maikor_version: u16,
65 pub ram_bank_count: u8,
67 pub name: String,
69 pub version: String,
71 pub author: String,
73 pub code_bank_count: u8,
74 pub atlas_bank_count: u8,
75}
76
77pub struct GameFile {
79 pub header: GameFileHeader,
80 pub main_code: [u8; MAIN_CODE],
82 pub code_banks: Vec<[u8; CODE_BANK]>,
84 pub atlases: Vec<[u8; ATLAS_BANK]>,
86}