use super::helpers::{
load_cgb_rom, load_cgb_rom_with_model, load_gb_rom, load_gb_rom_with_model, run_frames_and_crc,
run_one_frame, save_screen_png,
};
use crate::gb::bus::GbBus;
use crate::gb::model::{CgbModel, DmgModel};
const ACID_DIR: &str = "roms/gb/automated_tests/acid";
const WHICH_GB_DMG_FRAMES: u32 = 500;
const WHICH_GB_CGB_FRAMES: u32 = 100;
fn which_gb_path() -> String {
format!("{ACID_DIR}/which.gb")
}
fn assert_which_gb_dmg_crc(model: DmgModel, label: &str, expected_crc: u32) {
let mut gb = load_gb_rom_with_model(&which_gb_path(), model);
let crc = run_frames_and_crc(&mut gb, WHICH_GB_DMG_FRAMES);
assert_eq!(
crc, expected_crc,
"which.gb {label} frame CRC mismatch: got {crc:#010X}, expected {expected_crc:#010X}"
);
}
fn assert_which_gb_cgb_crc(model: CgbModel, label: &str, expected_crc: u32) {
let mut gb = load_cgb_rom_with_model(&which_gb_path(), model);
let crc = run_frames_and_crc(&mut gb, WHICH_GB_CGB_FRAMES);
assert_eq!(
crc, expected_crc,
"which.gb {label} frame CRC mismatch: got {crc:#010X}, expected {expected_crc:#010X}"
);
}
fn save_which_gb_dmg_capture(model: DmgModel, label: &str, path: &str) {
let mut gb = load_gb_rom_with_model(&which_gb_path(), model);
for _ in 0..WHICH_GB_DMG_FRAMES {
run_one_frame(&mut gb);
}
save_screen_png(&gb, path);
println!(
"{label} screenshot saved to {path}; CRC: {:#010X}",
gb.cpu.bus.ppu().screen_buffer().crc32()
);
}
fn save_which_gb_cgb_capture(model: CgbModel, label: &str, path: &str) {
let mut gb = load_cgb_rom_with_model(&which_gb_path(), model);
for _ in 0..WHICH_GB_CGB_FRAMES {
run_one_frame(&mut gb);
}
save_screen_png(&gb, path);
println!(
"{label} screenshot saved to {path}; CRC: {:#010X}",
gb.cpu.bus.ppu().screen_buffer().crc32()
);
}
#[test]
fn test_dmg_acid2_frame_matches_reference_crc() {
let mut gb = load_gb_rom(&format!("{ACID_DIR}/dmg-acid2.gb"));
let crc = run_frames_and_crc(&mut gb, 500);
const EXPECTED_CRC: u32 = 0x52D1_8222;
assert_eq!(
crc, EXPECTED_CRC,
"dmg-acid2 frame CRC mismatch: got {crc:#010X}, expected {EXPECTED_CRC:#010X}"
);
}
#[test]
fn test_cgb_acid2_frame_matches_reference_crc() {
let mut gb = load_cgb_rom(&format!("{ACID_DIR}/cgb-acid2.gbc"));
let crc = run_frames_and_crc(&mut gb, 200);
const EXPECTED_CRC: u32 = 0x0E0B_C136;
assert_eq!(
crc, EXPECTED_CRC,
"cgb-acid2 frame CRC mismatch: got {crc:#010X}, expected {EXPECTED_CRC:#010X}"
);
}
#[test]
fn test_cgb_acid_hell_frame_matches_reference_crc() {
let mut gb = load_cgb_rom(&format!("{ACID_DIR}/cgb-acid-hell.gbc"));
let crc = run_frames_and_crc(&mut gb, 200);
const EXPECTED_CRC: u32 = 0x1D55_EC40;
assert_eq!(
crc, EXPECTED_CRC,
"cgb-acid-hell frame CRC mismatch: got {crc:#010X}, expected {EXPECTED_CRC:#010X}"
);
}
#[test]
fn test_which_gb_frame_matches_reference_crc_on_dmg_0() {
assert_which_gb_dmg_crc(DmgModel::Dmg0, "DMG-0", 0x72DF_46F3);
}
#[test]
fn test_which_gb_frame_matches_reference_crc_on_dmg_b() {
assert_which_gb_dmg_crc(DmgModel::DmgB, "DMG-B", 0x3BC7_E8E8);
}
#[test]
fn test_which_gb_frame_matches_reference_crc_on_cgb_0() {
assert_which_gb_cgb_crc(CgbModel::Cgb0, "CGB-0", 0xA484_9AC3);
}
#[test]
fn test_which_gb_frame_matches_reference_crc_on_cgb_c() {
assert_which_gb_cgb_crc(CgbModel::CgbC, "CGB-C", 0x930E_6D5E);
}
#[test]
fn test_which_gb_frame_matches_reference_crc_on_cgb_e() {
assert_which_gb_cgb_crc(CgbModel::CgbE, "CGB-E", 0x8DCF_BF6E);
}
#[test]
fn test_which_gb_frame_matches_reference_crc_on_cgb_d() {
assert_which_gb_cgb_crc(CgbModel::CgbD, "CGB-D", 0x07E4_EFB1);
}
#[test]
#[ignore = "screenshot helper — run manually for visual baseline inspection"]
fn save_dmg_acid2_screenshot() {
let mut gb = load_gb_rom(&format!("{ACID_DIR}/dmg-acid2.gb"));
for _ in 0..500 {
run_one_frame(&mut gb);
}
save_screen_png(&gb, "dmg-acid2-screenshot.png");
println!("Screenshot saved to dmg-acid2-screenshot.png");
println!("CRC: {:#010X}", gb.cpu.bus.ppu().screen_buffer().crc32());
}
#[test]
#[ignore = "screenshot helper — run manually for visual baseline inspection"]
fn save_cgb_acid2_screenshot() {
let mut gb = load_cgb_rom(&format!("{ACID_DIR}/cgb-acid2.gbc"));
for _ in 0..200 {
run_one_frame(&mut gb);
}
save_screen_png(&gb, "cgb-acid2-screenshot.png");
println!("Screenshot saved to cgb-acid2-screenshot.png");
println!("CRC: {:#010X}", gb.cpu.bus.ppu().screen_buffer().crc32());
}
#[test]
#[ignore = "screenshot helper — run manually for visual baseline inspection"]
fn save_cgb_acid_hell_screenshot() {
let mut gb = load_cgb_rom(&format!("{ACID_DIR}/cgb-acid-hell.gbc"));
for _ in 0..200 {
run_one_frame(&mut gb);
}
save_screen_png(&gb, "cgb-acid-hell-screenshot.png");
println!("Screenshot saved to cgb-acid-hell-screenshot.png");
println!("CRC: {:#010X}", gb.cpu.bus.ppu().screen_buffer().crc32());
}
#[test]
#[ignore = "screenshot helper - run manually for visual baseline inspection"]
fn save_which_gb_screenshots() {
save_which_gb_dmg_capture(DmgModel::Dmg0, "DMG-0", "which-gb-dmg-0-screenshot.png");
save_which_gb_dmg_capture(DmgModel::DmgB, "DMG-B", "which-gb-dmg-b-screenshot.png");
save_which_gb_cgb_capture(CgbModel::Cgb0, "CGB-0", "which-gb-cgb-0-screenshot.png");
save_which_gb_cgb_capture(CgbModel::CgbC, "CGB-C", "which-gb-cgb-c-screenshot.png");
save_which_gb_cgb_capture(CgbModel::CgbD, "CGB-D", "which-gb-cgb-d-screenshot.png");
save_which_gb_cgb_capture(CgbModel::CgbE, "CGB-E", "which-gb-cgb-e-screenshot.png");
}