maikor_vm_file/
lib.rs

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    ///Unique ID for app
58    pub id: String,
59    ///Build number of app (must be equal or higher than installed version)
60    pub build: u32,
61    ///Target Maikor version (used for compatibility)
62    pub compiled_for_maikor_version: u16,
63    ///Minimum supported Maikor Version (used for compatibility)
64    pub min_maikor_version: u16,
65    ///Number of RAM banks needed by game
66    pub ram_bank_count: u8,
67    ///Game name
68    pub name: String,
69    ///Game version
70    pub version: String,
71    ///Game author
72    pub author: String,
73    pub code_bank_count: u8,
74    pub atlas_bank_count: u8,
75}
76
77/// Full game file
78pub struct GameFile {
79    pub header: GameFileHeader,
80    ///Main code data
81    pub main_code: [u8; MAIN_CODE],
82    ///Code bank data
83    pub code_banks: Vec<[u8; CODE_BANK]>,
84    ///Atlas bank data
85    pub atlases: Vec<[u8; ATLAS_BANK]>,
86}