Merge pull request #38 from corwinkuiper/output-test

Support for testing the display of the GBA
This commit is contained in:
Corwin 2021-06-04 11:07:23 +01:00 committed by GitHub
commit e7a2faa248
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 376 additions and 6 deletions

View file

@ -1 +1,23 @@
include!(concat!(env!("OUT_DIR"), "/test_logo.rs"));
#[test_case]
fn logo_display(gba: &mut crate::Gba) {
let mut gfx = gba.display.video.tiled0();
gfx.set_background_palettes(PALETTE_DATA);
gfx.set_background_tilemap(0, TILE_DATA);
let mut back = gfx.get_background().unwrap();
let mut entries: [u16; 30 * 20] = [0; 30 * 20];
for tile_id in 0..(30 * 20) {
let palette_entry = PALETTE_ASSIGNMENT[tile_id as usize] as u16;
entries[tile_id as usize] = tile_id | (palette_entry << 12);
}
back.set_map(&entries, 30, 20);
back.set_position(0, 0);
back.show();
crate::assert_image_output("gfx/test_logo.png");
}

View file

@ -133,6 +133,17 @@ pub extern "C" fn main() -> ! {
loop {}
}
#[cfg(test)]
fn assert_image_output(image: &str) {
let mut mgba = crate::mgba::Mgba::new().unwrap();
mgba.print(
format_args!("image:{}", image),
crate::mgba::DebugLevel::Info,
)
.unwrap();
display::busy_wait_for_VBlank();
}
#[cfg(test)]
mod test {
use super::Gba;

View file

@ -1,5 +1,17 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "adler32"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "aho-corasick"
version = "0.7.15"
@ -35,6 +47,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bindgen"
version = "0.53.3"
@ -65,6 +83,18 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bytemuck"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.67"
@ -121,6 +151,81 @@ dependencies = [
"vec_map",
]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
"lazy_static",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"cfg-if 1.0.0",
"lazy_static",
]
[[package]]
name = "deflate"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
dependencies = [
"adler32",
"byteorder",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "env_logger"
version = "0.7.1"
@ -134,6 +239,16 @@ dependencies = [
"termcolor",
]
[[package]]
name = "gif"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a668f699973d0f573d15749b7002a9ac9e1f9c6b220e7b165601334c173d8de"
dependencies = [
"color_quant",
"weezl",
]
[[package]]
name = "glob"
version = "0.3.0"
@ -158,6 +273,25 @@ dependencies = [
"quick-error",
]
[[package]]
name = "image"
version = "0.23.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"gif",
"jpeg-decoder",
"num-iter",
"num-rational",
"num-traits",
"png",
"scoped_threadpool",
"tiff",
]
[[package]]
name = "jobserver"
version = "0.1.21"
@ -167,6 +301,15 @@ dependencies = [
"libc",
]
[[package]]
name = "jpeg-decoder"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2"
dependencies = [
"rayon",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -210,6 +353,15 @@ version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "memoffset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
"autocfg",
]
[[package]]
name = "mgba-test-runner"
version = "0.1.0"
@ -217,9 +369,29 @@ dependencies = [
"anyhow",
"bindgen",
"cc",
"image",
"regex",
]
[[package]]
name = "miniz_oxide"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
dependencies = [
"adler32",
]
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]]
name = "nom"
version = "5.1.2"
@ -230,12 +402,75 @@ dependencies = [
"version_check",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "png"
version = "0.16.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6"
dependencies = [
"bitflags",
"crc32fast",
"deflate",
"miniz_oxide 0.3.7",
]
[[package]]
name = "proc-macro2"
version = "1.0.27"
@ -260,6 +495,31 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]]
name = "regex"
version = "1.4.5"
@ -283,6 +543,18 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "scoped_threadpool"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "shlex"
version = "0.1.1"
@ -313,6 +585,17 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "tiff"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437"
dependencies = [
"jpeg-decoder",
"miniz_oxide 0.4.4",
"weezl",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
@ -337,6 +620,12 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "weezl"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e"
[[package]]
name = "which"
version = "3.1.1"

View file

@ -9,6 +9,7 @@ edition = "2018"
[dependencies]
regex = "1"
anyhow = "1.0"
image = "0.23"
[build-dependencies]
cc = { version = "1.0", features = ["parallel"] }

View file

@ -2,8 +2,10 @@
mod runner;
use anyhow::{anyhow, Error};
use image::io::Reader;
use io::Write;
use regex::Regex;
use runner::VideoBuffer;
use std::cell::RefCell;
use std::io;
use std::path::Path;
@ -20,13 +22,27 @@ fn test_file(file_to_run: &str) -> Status {
let finished = Rc::new(RefCell::new(Status::Running));
let debug_reader_mutex = Regex::new(r"^\[(.*)\] GBA Debug: (.*)$").unwrap();
let mut mgba = runner::MGBA::new(file_to_run);
let video_buffer = mgba.get_video_buffer();
let fin_closure = Rc::clone(&finished);
runner::set_logger(Box::new(move |message| {
if let Some(captures) = debug_reader_mutex.captures(message) {
let log_level = &captures[1];
let out = &captures[2];
if out.ends_with("...") {
if out.starts_with("image:") {
let image_path = out.strip_prefix("image:").unwrap();
match check_image_match(image_path, &video_buffer) {
Err(e) => {
println!("[failed]");
println!("{}", e);
let mut done = fin_closure.borrow_mut();
*done = Status::Failed;
}
Ok(_) => {}
}
} else if out.ends_with("...") {
print!("{}", out);
io::stdout().flush().expect("can't flush stdout");
} else {
@ -45,8 +61,6 @@ fn test_file(file_to_run: &str) -> Status {
}
}));
let mut mgba = runner::MGBA::new(file_to_run);
loop {
mgba.advance_frame();
let done = finished.borrow();
@ -81,9 +95,42 @@ fn main() -> Result<(), Error> {
fn gba_colour_to_rgba(colour: u32) -> [u8; 4] {
[
(((((colour) << 3) & 0xF8) * 0x21) >> 5) as u8,
(((((colour) >> 2) & 0xF8) * 0x21) >> 5) as u8,
(((((colour) >> 7) & 0xF8) * 0x21) >> 5) as u8,
((colour >> 0) & 0xFF) as u8,
((colour >> 8) & 0xFF) as u8,
((colour >> 16) & 0xFF) as u8,
255,
]
}
fn rgba_to_gba_to_rgba(c: [u8; 4]) -> [u8; 4] {
let mut n = c.clone();
n.iter_mut()
.for_each(|a| *a = ((((*a as u32 >> 3) << 3) * 0x21) >> 5) as u8);
n
}
fn check_image_match(image_path: &str, video_buffer: &VideoBuffer) -> Result<(), Error> {
let expected_image = Reader::open(image_path)?.decode()?;
let expected = expected_image
.as_rgba8()
.ok_or(anyhow!("cannot convert to rgba8"))?;
let (buf_dim_x, buf_dim_y) = video_buffer.get_size();
let (exp_dim_x, exp_dim_y) = expected.dimensions();
if (buf_dim_x != exp_dim_x) || (buf_dim_y != exp_dim_y) {
return Err(anyhow!("image sizes do not match"));
}
for y in 0..buf_dim_y {
for x in 0..buf_dim_x {
let video_pixel = video_buffer.get_pixel(x, y);
let image_pixel = expected.get_pixel(x, y);
let video_pixel = gba_colour_to_rgba(video_pixel);
let image_pixel = rgba_to_gba_to_rgba(image_pixel.0);
if image_pixel != video_pixel {
return Err(anyhow!("images do not match"));
}
}
}
Ok(())
}