use serde::{Deserialize, Serialize};
pub const AUTORUN_VERSION: u32 = 3;
pub const CHECKPOINT_INTERVAL_FRAMES: u32 = 300;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AutorunFrame {
pub player1: u8,
pub player2: u8,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AutorunCheckpoint {
pub frame_index: u32,
pub screen_crc: u32,
pub state_bytes: Vec<u8>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AutorunFile {
pub version: u32,
pub frames: Vec<AutorunFrame>,
pub checkpoints: Vec<AutorunCheckpoint>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_autorun_version_is_3() {
assert_eq!(AUTORUN_VERSION, 3);
}
#[test]
fn test_checkpoint_interval_is_300() {
assert_eq!(CHECKPOINT_INTERVAL_FRAMES, 300);
}
#[test]
fn test_autorun_file_has_checkpoints_field() {
let file = AutorunFile {
version: AUTORUN_VERSION,
frames: vec![],
checkpoints: vec![],
};
assert!(file.checkpoints.is_empty());
}
#[test]
fn test_autorun_checkpoint_fields() {
let cp = AutorunCheckpoint {
frame_index: 300,
screen_crc: 0xDEADBEEF,
state_bytes: vec![1, 2, 3],
};
assert_eq!(cp.frame_index, 300);
assert_eq!(cp.screen_crc, 0xDEADBEEF);
assert_eq!(cp.state_bytes, vec![1, 2, 3]);
}
#[test]
fn test_autorun_file_uses_checkpoints_instead_of_checksum() {
let file = AutorunFile {
version: AUTORUN_VERSION,
frames: vec![],
checkpoints: vec![AutorunCheckpoint {
frame_index: 0,
screen_crc: 0xABCD,
state_bytes: vec![],
}],
};
assert_eq!(file.checkpoints.last().unwrap().screen_crc, 0xABCD);
}
}