fix(lint): clear the clippy gate across examples and tests
80 findings, not the 14 the first run showed -- clippy stops at the first failing compilation unit, so `--keep-going` is what makes the list complete. 60 were machine-applicable (`cargo clippy --fix`). The rest by hand: * five descending `sort_by` -> `sort_by_key(Reverse(..))` * `chunks_exact(4)` on both sides of four zips, so the compared items stay `[u8; 4]` rather than one array against one slice * three `type` aliases for the census maps and the captured-quad tuple * `&PathBuf` -> `&Path` in two disc tests * two range loops; one of them keeps `#[allow(needless_range_loop)]` with the reason -- the index is into a map's value, which changes each iteration * the module doc list in `invert_capture` re-indented to markdown's rules * `blit`'s eight arguments get `#[allow(too_many_arguments)]`, not a struct One dead `let off = b.len();` in a `ratc` test is dropped rather than renamed. The sibling test at :162 is the one that asserts an offset; if this one was meant to as well, that is a test change and not a lint fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -81,7 +81,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
let mut degen = 0usize;
|
let mut degen = 0usize;
|
||||||
let (mut agree, mut counted) = (0usize, 0usize);
|
let (mut agree, mut counted) = (0usize, 0usize);
|
||||||
for t in idx.chunks_exact(3) {
|
for t in idx.as_chunks::<3>().0 {
|
||||||
let (x, y, z) = (t[0] as usize, t[1] as usize, t[2] as usize);
|
let (x, y, z) = (t[0] as usize, t[1] as usize, t[2] as usize);
|
||||||
if x == y || y == z || x == z {
|
if x == y || y == z || x == z {
|
||||||
degen += 1;
|
degen += 1;
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ fn main() {
|
|||||||
let ar = PakArchive::open(root.join("dat/GP_TITLE.pak")).expect("GP_TITLE");
|
let ar = PakArchive::open(root.join("dat/GP_TITLE.pak")).expect("GP_TITLE");
|
||||||
let (mut ok, mut bad, mut missing) = (0, 0, 0);
|
let (mut ok, mut bad, mut missing) = (0, 0, 0);
|
||||||
println!(
|
println!(
|
||||||
"{:<7} {:<22} {:<10} {:<10} {}",
|
"{:<7} {:<22} {:<10} {:<10} ",
|
||||||
"entry", "sprite", "expected", "accessor", ""
|
"entry", "sprite", "expected", "accessor"
|
||||||
);
|
);
|
||||||
for e in [2usize, 4, 5, 6] {
|
for e in [2usize, 4, 5, 6] {
|
||||||
let by = ar.read(&ar.entries()[e]).expect("entry");
|
let by = ar.read(&ar.entries()[e]).expect("entry");
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!(
|
println!(
|
||||||
"{:<10} {:<22} {:<10} {:>10} {}",
|
"{:<10} {:<22} {:<10} {:>10} measured blend",
|
||||||
"entry", "sprite", "+0x04", "bit 0x02", "measured blend"
|
"entry", "sprite", "+0x04", "bit 0x02"
|
||||||
);
|
);
|
||||||
let (mut tp, mut tn, mut fp, mut fnn, mut missing) = (0, 0, 0, 0, 0);
|
let (mut tp, mut tn, mut fp, mut fnn, mut missing) = (0, 0, 0, 0, 0);
|
||||||
for &(e, n, additive) in MEASURED {
|
for &(e, n, additive) in MEASURED {
|
||||||
@@ -269,6 +269,7 @@ fn decl_rivals() {
|
|||||||
.filter(|(e, n, _)| decl.contains_key(&(*e, n.to_string())))
|
.filter(|(e, n, _)| decl.contains_key(&(*e, n.to_string())))
|
||||||
.collect();
|
.collect();
|
||||||
let mut rivals = 0;
|
let mut rivals = 0;
|
||||||
|
#[allow(clippy::needless_range_loop)]
|
||||||
for w in 0..15 {
|
for w in 0..15 {
|
||||||
for bit in 0..32 {
|
for bit in 0..32 {
|
||||||
let (mut ok, mut s, mut c) = (true, false, false);
|
let (mut ok, mut s, mut c) = (true, false, false);
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ fn main() {
|
|||||||
let (mut cover_exact, mut cover_short, mut idx_equal, mut idx_partial) =
|
let (mut cover_exact, mut cover_short, mut idx_equal, mut idx_partial) =
|
||||||
(0usize, 0usize, 0usize, 0usize);
|
(0usize, 0usize, 0usize, 0usize);
|
||||||
let mut rows: Vec<(usize, String)> = Vec::new();
|
let mut rows: Vec<(usize, String)> = Vec::new();
|
||||||
for (_, (voff, ibs, vcount)) in per_buf.iter() {
|
for (voff, ibs, vcount) in per_buf.values() {
|
||||||
let batches = ibs.len();
|
let batches = ibs.len();
|
||||||
let total: u32 = ibs.iter().map(|i| i.icount).sum();
|
let total: u32 = ibs.iter().map(|i| i.icount).sum();
|
||||||
let lo = ibs.iter().map(|i| i.ibase).min().unwrap() as i64 - base_delta;
|
let lo = ibs.iter().map(|i| i.ibase).min().unwrap() as i64 - base_delta;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ fn main() {
|
|||||||
let text = std::fs::read_to_string(log).expect("log");
|
let text = std::fs::read_to_string(log).expect("log");
|
||||||
for d in parse_capture(&text) {
|
for d in parse_capture(&text) {
|
||||||
let k = d.ib.map(|i| (i.ibase, i.icount)).unwrap_or((0, 0));
|
let k = d.ib.map(|i| (i.ibase, i.icount)).unwrap_or((0, 0));
|
||||||
if d.ib.map_or(false, |i| i.head_len > 0)
|
if d.ib.is_some_and(|i| i.head_len > 0)
|
||||||
&& d.pos.len() >= 4
|
&& d.pos.len() >= 4
|
||||||
&& seen.insert((log.clone(), d.vbase, k))
|
&& seen.insert((log.clone(), d.vbase, k))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ fn main() {
|
|||||||
None => clusters.push((*s, 1)),
|
None => clusters.push((*s, 1)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clusters.sort_by(|x, y| y.1.cmp(&x.1));
|
clusters.sort_by_key(|x| std::cmp::Reverse(x.1));
|
||||||
let tops: Vec<String> = clusters
|
let tops: Vec<String> = clusters
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, n)| *n >= 3)
|
.filter(|(_, n)| *n >= 3)
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use sylpheed_formats::mesh::Xbg7Model;
|
use sylpheed_formats::mesh::Xbg7Model;
|
||||||
|
|
||||||
|
/// Every place one model name was seen: (container, verts, tris, span).
|
||||||
|
type Sightings = BTreeMap<String, Vec<(String, usize, usize, [i64; 3])>>;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let dir = std::env::args().nth(1).expect("resource3d dir");
|
let dir = std::env::args().nth(1).expect("resource3d dir");
|
||||||
let list = std::env::args().any(|a| a == "--list");
|
let list = std::env::args().any(|a| a == "--list");
|
||||||
@@ -23,7 +26,7 @@ fn main() {
|
|||||||
files.sort();
|
files.sort();
|
||||||
|
|
||||||
// name -> [(container, verts, tris, span)]
|
// name -> [(container, verts, tris, span)]
|
||||||
let mut seen: BTreeMap<String, Vec<(String, usize, usize, [i64; 3])>> = BTreeMap::new();
|
let mut seen: Sightings = BTreeMap::new();
|
||||||
for f in &files {
|
for f in &files {
|
||||||
let Ok(bytes) = std::fs::read(f) else {
|
let Ok(bytes) = std::fs::read(f) else {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ fn main() {
|
|||||||
}
|
}
|
||||||
println!("\n--- schema 0x{schema:08x} {name} ({n_obj} objects) ---");
|
println!("\n--- schema 0x{schema:08x} {name} ({n_obj} objects) ---");
|
||||||
println!(
|
println!(
|
||||||
"{:<30} {:>5} {:>5} {}",
|
"{:<30} {:>5} {:>5} values seen (≤12) | owners defaulting",
|
||||||
"KEY", "set", "dflt", "values seen (≤12) | owners defaulting"
|
"KEY", "set", "dflt"
|
||||||
);
|
);
|
||||||
for (k, (n_set, n_def, vals, owners)) in defaulted {
|
for (k, (n_set, n_def, vals, owners)) in defaulted {
|
||||||
let vv: Vec<&str> = vals.iter().map(|s| s.as_str()).collect();
|
let vv: Vec<&str> = vals.iter().map(|s| s.as_str()).collect();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ fn short(s: &str) -> String {
|
|||||||
.trim_start_matches("UnitName_UN_")
|
.trim_start_matches("UnitName_UN_")
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
fn g<'a>(o: &'a IdxdObject, k: &str) -> String {
|
fn g(o: &IdxdObject, k: &str) -> String {
|
||||||
o.get_f32(k)
|
o.get_f32(k)
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
if v == v.trunc() {
|
if v == v.trunc() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use sylpheed_formats::{game_data, localization::TextIndex, PakArchive};
|
use sylpheed_formats::{localization::TextIndex, PakArchive};
|
||||||
fn main() {
|
fn main() {
|
||||||
let disc = std::env::var("SYLPHEED_DISC").unwrap();
|
let disc = std::env::var("SYLPHEED_DISC").unwrap();
|
||||||
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).unwrap();
|
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).unwrap();
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let (mut shared, mut inconsistent) = (0usize, 0usize);
|
let (mut shared, mut inconsistent) = (0usize, 0usize);
|
||||||
for (_, list) in &seen {
|
for list in seen.values() {
|
||||||
if list.len() < 2 || !list.iter().all(|e| e.1 == list[0].1 && e.2 == list[0].2) {
|
if list.len() < 2 || !list.iter().all(|e| e.1 == list[0].1 && e.2 == list[0].2) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ fn all_descriptors(buf: &[u8]) -> Vec<(usize, u32)> {
|
|||||||
let mut o = 0;
|
let mut o = 0;
|
||||||
while o <= end {
|
while o <= end {
|
||||||
let id = be(o);
|
let id = be(o);
|
||||||
if id >= 1 && id < ID_MAX && be(o + 4) == DESC_MARK && be(o + DESC_REPEAT) == id {
|
if (1..ID_MAX).contains(&id) && be(o + 4) == DESC_MARK && be(o + DESC_REPEAT) == id {
|
||||||
out.push((o, id));
|
out.push((o, id));
|
||||||
}
|
}
|
||||||
o += 4;
|
o += 4;
|
||||||
|
|||||||
@@ -33,10 +33,12 @@ fn order_without_rule(build: &ui_layout::UiBuild, bundle: &[u8]) -> Vec<usize> {
|
|||||||
|
|
||||||
fn counts(rgba: &[u8], t: u8) -> (usize, usize) {
|
fn counts(rgba: &[u8], t: u8) -> (usize, usize) {
|
||||||
let rgb = rgba
|
let rgb = rgba
|
||||||
.chunks_exact(4)
|
.as_chunks::<4>()
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
.filter(|p| p[0] > t || p[1] > t || p[2] > t)
|
.filter(|p| p[0] > t || p[1] > t || p[2] > t)
|
||||||
.count();
|
.count();
|
||||||
let alpha = rgba.chunks_exact(4).filter(|p| p[3] > t).count();
|
let alpha = rgba.as_chunks::<4>().0.iter().filter(|p| p[3] > t).count();
|
||||||
(rgb, alpha)
|
(rgb, alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +71,7 @@ fn main() {
|
|||||||
] {
|
] {
|
||||||
let with = ui_layout::derived_paint_order(&b, &by);
|
let with = ui_layout::derived_paint_order(&b, &by);
|
||||||
let without = order_without_rule(&b, &by);
|
let without = order_without_rule(&b, &by);
|
||||||
let a = ui_layout::compose_with_order(&b, &by, opts.clone(), None, Some(&with));
|
let a = ui_layout::compose_with_order(&b, &by, opts, None, Some(&with));
|
||||||
let c = ui_layout::compose_with_order(&b, &by, opts, None, Some(&without));
|
let c = ui_layout::compose_with_order(&b, &by, opts, None, Some(&without));
|
||||||
println!(
|
println!(
|
||||||
"\n== GP_TITLE entry {entry} — {label} ({}x{})",
|
"\n== GP_TITLE entry {entry} — {label} ({}x{})",
|
||||||
@@ -85,8 +87,10 @@ fn main() {
|
|||||||
}
|
}
|
||||||
let changed = a
|
let changed = a
|
||||||
.rgba
|
.rgba
|
||||||
.chunks_exact(4)
|
.as_chunks::<4>()
|
||||||
.zip(c.rgba.chunks_exact(4))
|
.0
|
||||||
|
.iter()
|
||||||
|
.zip(c.rgba.as_chunks::<4>().0.iter())
|
||||||
.filter(|(x, y)| x != y)
|
.filter(|(x, y)| x != y)
|
||||||
.count();
|
.count();
|
||||||
println!(" exact-RGBA changed pixels between the two orders: {changed}");
|
println!(" exact-RGBA changed pixels between the two orders: {changed}");
|
||||||
|
|||||||
@@ -85,19 +85,23 @@ fn main() {
|
|||||||
.map(|el| el.name.as_str())
|
.map(|el| el.name.as_str())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let a = ui_layout::compose_with_order(&b, &by, opts.clone(), None, Some(&with));
|
let a = ui_layout::compose_with_order(&b, &by, opts, None, Some(&with));
|
||||||
let c = ui_layout::compose_with_order(&b, &by, opts.clone(), None, Some(&without));
|
let c = ui_layout::compose_with_order(&b, &by, opts, None, Some(&without));
|
||||||
let n = a
|
let n = a
|
||||||
.rgba
|
.rgba
|
||||||
.chunks_exact(4)
|
.as_chunks::<4>()
|
||||||
.zip(c.rgba.chunks_exact(4))
|
.0
|
||||||
|
.iter()
|
||||||
|
.zip(c.rgba.as_chunks::<4>().0.iter())
|
||||||
.filter(|(x, y)| x != y)
|
.filter(|(x, y)| x != y)
|
||||||
.count();
|
.count();
|
||||||
// Control: does this build put any ink down at all, against the bare
|
// Control: does this build put any ink down at all, against the bare
|
||||||
// backdrop? A build that renders to nothing cannot show a reorder.
|
// backdrop? A build that renders to nothing cannot show a reorder.
|
||||||
let ink = a
|
let ink = a
|
||||||
.rgba
|
.rgba
|
||||||
.chunks_exact(4)
|
.as_chunks::<4>()
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
.filter(|p| p[..3] != [0, 0, 0])
|
.filter(|p| p[..3] != [0, 0, 0])
|
||||||
.count();
|
.count();
|
||||||
let total = a.rgba.len() / 4;
|
let total = a.rgba.len() / 4;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ fn census(name: &str, img: &t8ad::T8adImage) {
|
|||||||
.map(|a| (hist[a], a))
|
.map(|a| (hist[a], a))
|
||||||
.filter(|&(c, _)| c > 0)
|
.filter(|&(c, _)| c > 0)
|
||||||
.collect();
|
.collect();
|
||||||
top.sort_unstable_by(|a, b| b.0.cmp(&a.0));
|
top.sort_unstable_by_key(|a| std::cmp::Reverse(a.0));
|
||||||
let top5: Vec<String> = top
|
let top5: Vec<String> = top
|
||||||
.iter()
|
.iter()
|
||||||
.take(5)
|
.take(5)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ fn score(idx: &[u32], pos: &[[f32; 3]], nrm: &[[f32; 3]]) -> (usize, f32, usize)
|
|||||||
let mut degen = 0usize;
|
let mut degen = 0usize;
|
||||||
let mut agree = 0usize;
|
let mut agree = 0usize;
|
||||||
let mut counted = 0usize;
|
let mut counted = 0usize;
|
||||||
for t in idx.chunks_exact(3) {
|
for t in idx.as_chunks::<3>().0 {
|
||||||
let (a, b, c) = (t[0] as usize, t[1] as usize, t[2] as usize);
|
let (a, b, c) = (t[0] as usize, t[1] as usize, t[2] as usize);
|
||||||
if a == b || b == c || a == c {
|
if a == b || b == c || a == c {
|
||||||
degen += 1;
|
degen += 1;
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
//!
|
//!
|
||||||
//! This is the diagnostic for the 2026-07-31 negative result (Stage_S02 capture,
|
//! This is the diagnostic for the 2026-07-31 negative result (Stage_S02 capture,
|
||||||
//! zero parts correlated). It separates three hypotheses:
|
//! zero parts correlated). It separates three hypotheses:
|
||||||
//! 1. LOD/variant vcount not covered by the correlator's variant list
|
//! 1. LOD/variant vcount not covered by the correlator's variant list
|
||||||
//! → the big draws DO map to named resources, just not to the `_m`/`_l`/`_d`
|
//! → the big draws DO map to named resources, just not to the `_m`/`_l`/`_d`
|
||||||
//! set the correlator tries;
|
//! set the correlator tries;
|
||||||
//! 2. position validation over-rejects
|
//! 2. position validation over-rejects
|
||||||
//! → the vcounts match the very parts we asked for (so the vcount key was
|
//! → the vcounts match the very parts we asked for (so the vcount key was
|
||||||
//! fine and the rejection happened later);
|
//! fine and the rejection happened later);
|
||||||
//! 3. a different draw path (instanced/batched/merged buffers)
|
//! 3. a different draw path (instanced/batched/merged buffers)
|
||||||
//! → the big draws match NO resource in the container at all.
|
//! → the big draws match NO resource in the container at all.
|
||||||
//!
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//! SYLPHEED_ISO=... cargo run --release --example invert_capture -- \
|
//! SYLPHEED_ISO=... cargo run --release --example invert_capture -- \
|
||||||
@@ -171,7 +171,7 @@ fn main() {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
sizes.sort_unstable_by(|a, b| b.0.cmp(&a.0));
|
sizes.sort_unstable_by_key(|a| std::cmp::Reverse(a.0));
|
||||||
println!("\nlargest resources in {stage}.xpr → drawn in the capture?");
|
println!("\nlargest resources in {stage}.xpr → drawn in the capture?");
|
||||||
for (v, name) in sizes.iter().take(top_n.min(sizes.len())) {
|
for (v, name) in sizes.iter().take(top_n.min(sizes.len())) {
|
||||||
let n = draw_count.get(v).copied().unwrap_or(0);
|
let n = draw_count.get(v).copied().unwrap_or(0);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("GP_TITLE: {builds} parseable builds of {n} entries\n");
|
println!("GP_TITLE: {builds} parseable builds of {n} entries\n");
|
||||||
println!("{:<10} {}", "kind", "elements by file suffix");
|
println!("{:<10} elements by file suffix", "kind");
|
||||||
for (k, m) in &table {
|
for (k, m) in &table {
|
||||||
let s: Vec<String> = m.iter().map(|(sfx, c)| format!("{sfx}x{c}")).collect();
|
let s: Vec<String> = m.iter().map(|(sfx, c)| format!("{sfx}x{c}")).collect();
|
||||||
println!("0x{k:<8X} {}", s.join(" "));
|
println!("0x{k:<8X} {}", s.join(" "));
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ fn main() {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let n = b.elements.len();
|
let n = b.elements.len();
|
||||||
let base = ui_layout::compose(&b, &by, o.clone(), None);
|
let base = ui_layout::compose(&b, &by, o, None);
|
||||||
std::fs::write(format!("{dir}/base.raw"), &base.rgba).unwrap();
|
std::fs::write(format!("{dir}/base.raw"), &base.rgba).unwrap();
|
||||||
println!("canvas {}x{} elements {n}", base.width, base.height);
|
println!("canvas {}x{} elements {n}", base.width, base.height);
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
@@ -22,7 +22,7 @@ fn main() {
|
|||||||
// only bother with elements whose rest pose can touch the band
|
// only bother with elements whose rest pose can touch the band
|
||||||
let mut v = vec![true; n];
|
let mut v = vec![true; n];
|
||||||
v[i] = false;
|
v[i] = false;
|
||||||
let c = ui_layout::compose(&b, &by, o.clone(), Some(&v));
|
let c = ui_layout::compose(&b, &by, o, Some(&v));
|
||||||
std::fs::write(format!("{dir}/wo-{i}.raw"), &c.rgba).unwrap();
|
std::fs::write(format!("{dir}/wo-{i}.raw"), &c.rgba).unwrap();
|
||||||
println!(
|
println!(
|
||||||
"{i}\t{}\t{}\t({},{})\ta={}",
|
"{i}\t{}\t{}\t({},{})\ta={}",
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ fn main() {
|
|||||||
let Some(b) = ui_layout::parse_build(&by) else {
|
let Some(b) = ui_layout::parse_build(&by) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
for (_, (off, size)) in &b.records {
|
for (off, size) in b.records.values() {
|
||||||
let rec = &by[*off..(*off + *size).min(by.len())];
|
let rec = &by[*off..(*off + *size).min(by.len())];
|
||||||
if rec.len() < 0x10 || &rec[0..4] != b"RATC" {
|
if rec.len() < 0x10 || &rec[0..4] != b"RATC" {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ fn main() {
|
|||||||
let by = ar.read(&ar.entries()[5]).expect("entry 5");
|
let by = ar.read(&ar.entries()[5]).expect("entry 5");
|
||||||
let b = ui_layout::parse_build(&by).expect("build");
|
let b = ui_layout::parse_build(&by).expect("build");
|
||||||
println!(
|
println!(
|
||||||
"{:<26} {:>6} {:>6} {:>7} {:>7} {}",
|
"{:<26} {:>6} {:>6} {:>7} {:>7} sprite",
|
||||||
"element", "x", "y", "pivot_x", "pivot_y", "sprite"
|
"element", "x", "y", "pivot_x", "pivot_y"
|
||||||
);
|
);
|
||||||
let mut rows: Vec<(i32, i32, String, String)> = b
|
let mut rows: Vec<(i32, i32, String, String)> = b
|
||||||
.elements
|
.elements
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ fn be16(b: &[u8], at: usize) -> u32 {
|
|||||||
/// folded to `max(na, 1-na)` so both authored windings read as ≈1.
|
/// folded to `max(na, 1-na)` so both authored windings read as ≈1.
|
||||||
fn winding(idx: &[u32], pos: &[[f32; 3]], nrm: &[[f32; 3]]) -> f32 {
|
fn winding(idx: &[u32], pos: &[[f32; 3]], nrm: &[[f32; 3]]) -> f32 {
|
||||||
let (mut agree, mut n) = (0usize, 0usize);
|
let (mut agree, mut n) = (0usize, 0usize);
|
||||||
for t in idx.chunks_exact(3) {
|
for t in idx.as_chunks::<3>().0 {
|
||||||
let (a, b, c) = (t[0] as usize, t[1] as usize, t[2] as usize);
|
let (a, b, c) = (t[0] as usize, t[1] as usize, t[2] as usize);
|
||||||
if a == b || b == c || a == c || a.max(b).max(c) >= pos.len() || a >= nrm.len() {
|
if a == b || b == c || a == c || a.max(b).max(c) >= pos.len() || a >= nrm.len() {
|
||||||
continue;
|
continue;
|
||||||
@@ -51,7 +51,9 @@ fn winding(idx: &[u32], pos: &[[f32; 3]], nrm: &[[f32; 3]]) -> f32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn degenerate(idx: &[u32]) -> usize {
|
fn degenerate(idx: &[u32]) -> usize {
|
||||||
idx.chunks_exact(3)
|
idx.as_chunks::<3>()
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
.filter(|t| t[0] == t[1] || t[1] == t[2] || t[0] == t[2])
|
.filter(|t| t[0] == t[1] || t[1] == t[2] || t[0] == t[2])
|
||||||
.count()
|
.count()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ fn main() {
|
|||||||
if tok == &key {
|
if tok == &key {
|
||||||
let lo = i.saturating_sub(6);
|
let lo = i.saturating_sub(6);
|
||||||
let hi = (i + 7).min(t.len());
|
let hi = (i + 7).min(t.len());
|
||||||
for j in lo..hi {
|
for (j, tok_j) in t.iter().enumerate().skip(lo).take(hi - lo) {
|
||||||
println!(
|
println!(
|
||||||
" [{j}]{} {:?}",
|
" [{j}]{} {:?}",
|
||||||
if j == i { " <-- key" } else { " " },
|
if j == i { " <-- key" } else { " " },
|
||||||
t[j]
|
tok_j
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ fn forced(b: &ui_layout::UiBuild, el: &ui_layout::Element, tmax: u32, hold: bool
|
|||||||
if el.sprite.is_some() {
|
if el.sprite.is_some() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if (el.pivot_x * 2) < b.design_w as u32 || (el.pivot_y * 2) < b.design_h as u32 {
|
if (el.pivot_x * 2) < b.design_w || (el.pivot_y * 2) < b.design_h {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if tmax == 0 {
|
if tmax == 0 {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ fn main() {
|
|||||||
let mut prev = None;
|
let mut prev = None;
|
||||||
for t in 0..=span {
|
for t in 0..=span {
|
||||||
if let Some(k) = le.pose_at(t) {
|
if let Some(k) = le.pose_at(t) {
|
||||||
if prev.map_or(false, |p| p != k.x) {
|
if prev.is_some_and(|p| p != k.x) {
|
||||||
last_move = t
|
last_move = t
|
||||||
}
|
}
|
||||||
prev = Some(k.x);
|
prev = Some(k.x);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ fn main() {
|
|||||||
if let Some(out) = std::env::args().nth(2) {
|
if let Some(out) = std::env::args().nth(2) {
|
||||||
// Dependency-free PPM (P6, RGB — alpha already composited over the backdrop).
|
// Dependency-free PPM (P6, RGB — alpha already composited over the backdrop).
|
||||||
let mut buf = format!("P6\n{} {}\n255\n", screen.width, screen.height).into_bytes();
|
let mut buf = format!("P6\n{} {}\n255\n", screen.width, screen.height).into_bytes();
|
||||||
for px in screen.rgba.chunks_exact(4) {
|
for px in screen.rgba.as_chunks::<4>().0 {
|
||||||
buf.extend_from_slice(&px[..3]);
|
buf.extend_from_slice(&px[..3]);
|
||||||
}
|
}
|
||||||
std::fs::write(&out, buf).unwrap();
|
std::fs::write(&out, buf).unwrap();
|
||||||
|
|||||||
@@ -78,12 +78,12 @@ fn main() {
|
|||||||
println!(" {fb_visible} of those rest at alpha > 0 -- i.e. VISIBLE\n");
|
println!(" {fb_visible} of those rest at alpha > 0 -- i.e. VISIBLE\n");
|
||||||
println!("PER ARCHIVE — fallback fires / of those, rests VISIBLE:");
|
println!("PER ARCHIVE — fallback fires / of those, rests VISIBLE:");
|
||||||
let mut rows: Vec<_> = per_pak.into_iter().collect();
|
let mut rows: Vec<_> = per_pak.into_iter().collect();
|
||||||
rows.sort_by(|a, b| b.1 .1.cmp(&a.1 .1));
|
rows.sort_by_key(|a| std::cmp::Reverse(a.1 .1));
|
||||||
for (pak, (fires, vis)) in &rows {
|
for (pak, (fires, vis)) in &rows {
|
||||||
println!(" {pak:34} {fires:5} fires {vis:5} visible");
|
println!(" {pak:34} {fires:5} fires {vis:5} visible");
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
worst.sort_by(|a, b| b.0.cmp(&a.0));
|
worst.sort_by_key(|a| std::cmp::Reverse(a.0));
|
||||||
for (a, pak, el) in worst.iter().take(6) {
|
for (a, pak, el) in worst.iter().take(6) {
|
||||||
println!(" a={a:3} {pak} {el}");
|
println!(" a={a:3} {pak} {el}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ fn main() {
|
|||||||
};
|
};
|
||||||
println!("=== {pak} entry {build} ===");
|
println!("=== {pak} entry {build} ===");
|
||||||
println!(
|
println!(
|
||||||
"{:<22} {:>10} {:>7} {:>7} {:>12} {}",
|
"{:<22} {:>10} {:>7} {:>7} {:>12} at 1x/2x of pivot*2",
|
||||||
"element", "pivot(w,h)", "sx%", "sy%", "drawn px", "at 1x/2x of pivot*2"
|
"element", "pivot(w,h)", "sx%", "sy%", "drawn px"
|
||||||
);
|
);
|
||||||
for e in &b.elements {
|
for e in &b.elements {
|
||||||
let k = match e.rest() {
|
let k = match e.rest() {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ fn main() {
|
|||||||
println!("\nunion of all element keyframe times: {ts:?}");
|
println!("\nunion of all element keyframe times: {ts:?}");
|
||||||
let gaps: Vec<(u32, u32, u32)> = ts.windows(2).map(|w| (w[1] - w[0], w[0], w[1])).collect();
|
let gaps: Vec<(u32, u32, u32)> = ts.windows(2).map(|w| (w[1] - w[0], w[0], w[1])).collect();
|
||||||
let mut g = gaps.clone();
|
let mut g = gaps.clone();
|
||||||
g.sort_by(|a, b| b.0.cmp(&a.0));
|
g.sort_by_key(|a| std::cmp::Reverse(a.0));
|
||||||
println!("widest gaps: {:?}", &g[..g.len().min(4)]);
|
println!("widest gaps: {:?}", &g[..g.len().min(4)]);
|
||||||
println!("settle_window() reports {:?}", build.settle_window());
|
println!("settle_window() reports {:?}", build.settle_window());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ fn main() {
|
|||||||
hi[k] = hi[k].max(v[k]);
|
hi[k] = hi[k].max(v[k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for t in sub.indices.chunks_exact(3) {
|
for t in sub.indices.as_chunks::<3>().0 {
|
||||||
tris.push([w[t[0] as usize], w[t[1] as usize], w[t[2] as usize]]);
|
tris.push([w[t[0] as usize], w[t[1] as usize], w[t[2] as usize]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ fn main() {
|
|||||||
.or_default()
|
.or_default()
|
||||||
.push((m.name.clone(), thin));
|
.push((m.name.clone(), thin));
|
||||||
}
|
}
|
||||||
for (id, parts) in &by_ship {
|
for parts in by_ship.values() {
|
||||||
if parts.len() < 3 {
|
if parts.len() < 3 {
|
||||||
continue; // no meaningful median
|
continue; // no meaningful median
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ fn main() {
|
|||||||
};
|
};
|
||||||
has_riff += 1;
|
has_riff += 1;
|
||||||
if ri > slb::HEADERLESS_DATA_OFFSET
|
if ri > slb::HEADERLESS_DATA_OFFSET
|
||||||
&& (ri - slb::HEADERLESS_DATA_OFFSET) % slb::XMA1_PACKET == 0
|
&& (ri - slb::HEADERLESS_DATA_OFFSET).is_multiple_of(slb::XMA1_PACKET)
|
||||||
{
|
{
|
||||||
hybrid += 1;
|
hybrid += 1;
|
||||||
if b[slb::HEADERLESS_DATA_OFFSET..ri].iter().any(|x| *x != 0) {
|
if b[slb::HEADERLESS_DATA_OFFSET..ri].iter().any(|x| *x != 0) {
|
||||||
|
|||||||
@@ -21,9 +21,12 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use sylpheed_formats::{pak::PakArchive, t8ad, ui_layout};
|
use sylpheed_formats::{pak::PakArchive, t8ad, ui_layout};
|
||||||
|
|
||||||
|
/// One captured quad: (name, x, y, w, h, index).
|
||||||
|
type CapturedQuad = (&'static str, f64, f64, f64, f64, usize);
|
||||||
|
|
||||||
/// The oracle. Verbatim from the header of `docs/re/data/splash-quad-timeline.txt`,
|
/// The oracle. Verbatim from the header of `docs/re/data/splash-quad-timeline.txt`,
|
||||||
/// which read them off the vertex buffer. Quantised to 0.01 by that file.
|
/// which read them off the vertex buffer. Quantised to 0.01 by that file.
|
||||||
const CAPTURED: &[(&str, f64, f64, f64, f64, usize)] = &[
|
const CAPTURED: &[CapturedQuad] = &[
|
||||||
// name, x0, x1, y0, y1, draws submitted in
|
// name, x0, x1, y0, y1, draws submitted in
|
||||||
("Q0", -0.520, 0.520, -0.100, 0.080, 111),
|
("Q0", -0.520, 0.520, -0.100, 0.080, 111),
|
||||||
("Q1", -0.390, 0.390, 0.350, 0.550, 87),
|
("Q1", -0.390, 0.390, 0.350, 0.550, 87),
|
||||||
@@ -83,14 +86,13 @@ fn main() {
|
|||||||
// a step plus the pixel grid: 0.01 NDC is 6.4 px in x, 3.6 px in y.
|
// a step plus the pixel grid: 0.01 NDC is 6.4 px in x, 3.6 px in y.
|
||||||
const TOL: f64 = 0.010;
|
const TOL: f64 = 0.010;
|
||||||
println!(
|
println!(
|
||||||
"{:<26} {:<4} {:>8} {:>9} {:>7} {}",
|
"{:<26} {:<4} {:>8} {:>9} {:>7} verdict",
|
||||||
"sprite (disc)", "quad", "max|d|", "runner-up", "draws", "verdict"
|
"sprite (disc)", "quad", "max|d|", "runner-up", "draws"
|
||||||
);
|
);
|
||||||
let (mut ok, mut bad) = (0, 0);
|
let (mut ok, mut bad) = (0, 0);
|
||||||
let mut used: Vec<&str> = Vec::new();
|
let mut used: Vec<&str> = Vec::new();
|
||||||
for p in &predicted {
|
for p in &predicted {
|
||||||
let mut ds: Vec<(f64, &(&str, f64, f64, f64, f64, usize))> =
|
let mut ds: Vec<(f64, &CapturedQuad)> = CAPTURED.iter().map(|c| (dist(p, c), c)).collect();
|
||||||
CAPTURED.iter().map(|c| (dist(p, c), c)).collect();
|
|
||||||
ds.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
|
ds.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
|
||||||
let (d0, best) = (ds[0].0, ds[0].1);
|
let (d0, best) = (ds[0].0, ds[0].1);
|
||||||
let d1 = ds[1].0;
|
let d1 = ds[1].0;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ fn main() {
|
|||||||
let Some(b) = ui_layout::parse_build(&by) else {
|
let Some(b) = ui_layout::parse_build(&by) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
for (_, (off, size)) in &b.records {
|
for (off, size) in b.records.values() {
|
||||||
let rec = &by[*off..(*off + *size).min(by.len())];
|
let rec = &by[*off..(*off + *size).min(by.len())];
|
||||||
if rec.len() < 0x10 || &rec[0..4] != b"RATC" {
|
if rec.len() < 0x10 || &rec[0..4] != b"RATC" {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use ui_layout::{ComposeOptions, UiBuild};
|
|||||||
/// Pixels that differ, and the largest per-channel difference.
|
/// Pixels that differ, and the largest per-channel difference.
|
||||||
fn diff(a: &[u8], b: &[u8]) -> (usize, u8) {
|
fn diff(a: &[u8], b: &[u8]) -> (usize, u8) {
|
||||||
let (mut n, mut worst) = (0usize, 0u8);
|
let (mut n, mut worst) = (0usize, 0u8);
|
||||||
for (pa, pb) in a.chunks_exact(4).zip(b.chunks_exact(4)) {
|
for (pa, pb) in a.as_chunks::<4>().0.iter().zip(b.as_chunks::<4>().0.iter()) {
|
||||||
if pa != pb {
|
if pa != pb {
|
||||||
n += 1;
|
n += 1;
|
||||||
for k in 0..4 {
|
for k in 0..4 {
|
||||||
@@ -51,8 +51,10 @@ fn ink_mask(
|
|||||||
let mut vis = vec![true; n_el.max(build.elements.len())];
|
let mut vis = vec![true; n_el.max(build.elements.len())];
|
||||||
vis[build.elements[ei].index] = false;
|
vis[build.elements[ei].index] = false;
|
||||||
let without = ui_layout::compose_with_order(build, bundle, opts, Some(&vis), Some(order));
|
let without = ui_layout::compose_with_order(build, bundle, opts, Some(&vis), Some(order));
|
||||||
base.chunks_exact(4)
|
base.as_chunks::<4>()
|
||||||
.zip(without.rgba.chunks_exact(4))
|
.0
|
||||||
|
.iter()
|
||||||
|
.zip(without.rgba.as_chunks::<4>().0.iter())
|
||||||
.map(|(x, y)| x != y)
|
.map(|(x, y)| x != y)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,7 @@ fn swapped(order: &[usize], a: usize, b: usize) -> Vec<usize> {
|
|||||||
fn rect(e: &ui_layout::Element, at: Option<u32>) -> Option<(i32, i32, i32, i32)> {
|
fn rect(e: &ui_layout::Element, at: Option<u32>) -> Option<(i32, i32, i32, i32)> {
|
||||||
let kf = match at {
|
let kf = match at {
|
||||||
Some(t) => e.pose_at(t)?,
|
Some(t) => e.pose_at(t)?,
|
||||||
None => e.rest()?.clone(),
|
None => *e.rest()?,
|
||||||
};
|
};
|
||||||
if kf.fade >> 24 == 0 || kf.scale_x == 0 || kf.scale_y == 0 {
|
if kf.fade >> 24 == 0 || kf.scale_x == 0 || kf.scale_y == 0 {
|
||||||
return None;
|
return None;
|
||||||
@@ -183,7 +185,7 @@ fn control_pair(build: &UiBuild, bytes: &[u8], at: Option<u32>) -> Option<(usize
|
|||||||
let ox = ((ra.0 + ra.2).min(rb.0 + rb.2) - ra.0.max(rb.0)) as i64;
|
let ox = ((ra.0 + ra.2).min(rb.0 + rb.2) - ra.0.max(rb.0)) as i64;
|
||||||
let oy = ((ra.1 + ra.3).min(rb.1 + rb.3) - ra.1.max(rb.1)) as i64;
|
let oy = ((ra.1 + ra.3).min(rb.1 + rb.3) - ra.1.max(rb.1)) as i64;
|
||||||
let area = ox * oy;
|
let area = ox * oy;
|
||||||
if best.map_or(true, |(x, _, _)| area > x) {
|
if best.is_none_or(|(x, _, _)| area > x) {
|
||||||
best = Some((area, a, b));
|
best = Some((area, a, b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ fn rect(e: &ui_layout::Element, t: u32) -> Option<(i32, i32, i32, i32)> {
|
|||||||
Some((kf.x, kf.y, w, h))
|
Some((kf.x, kf.y, w, h))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn live_pairs(b: &UiBuild, bytes: &[u8], keys: &[u32], t: u32) -> usize {
|
fn live_pairs(b: &UiBuild, _bytes: &[u8], keys: &[u32], t: u32) -> usize {
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
for a in 0..keys.len() {
|
for a in 0..keys.len() {
|
||||||
for c in (a + 1)..keys.len() {
|
for c in (a + 1)..keys.len() {
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
// spanning?
|
// spanning?
|
||||||
let span_adv_end = 437547264u64;
|
let span_adv_end = 437547264u64;
|
||||||
let spans = start < span_adv_end && end > span_adv_end || (start / 1_000 != end / 1_000);
|
let _spans = start < span_adv_end && end > span_adv_end || (start / 1_000 != end / 1_000);
|
||||||
println!("cue {id} ({mov}): region[{start}..{end}] {} bytes, {} riff(s), Σ={:.1}s | movie={} parts={:?}",
|
println!("cue {id} ({mov}): region[{start}..{end}] {} bytes, {} riff(s), Σ={:.1}s | movie={} parts={:?}",
|
||||||
end-start, riffs.len(), total, movdur(&disc,mov), parts);
|
end-start, riffs.len(), total, movdur(&disc,mov), parts);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ fn main() {
|
|||||||
println!(
|
println!(
|
||||||
" {n} chunk(s): {:>3} region(s) {}",
|
" {n} chunk(s): {:>3} region(s) {}",
|
||||||
ms.len(),
|
ms.len(),
|
||||||
ms.iter().cloned().collect::<Vec<_>>().join(" ")
|
ms.to_vec().join(" ")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
println!(
|
println!(
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ fn main() {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"{:10} {:>8} {:>12} {:>10} {}",
|
"{:10} {:>8} {:>12} {:>10} verdict",
|
||||||
"movie", "chunks", "first chunk", "clip pkts", "verdict"
|
"movie", "chunks", "first chunk", "clip pkts"
|
||||||
);
|
);
|
||||||
let (mut clipped, mut clean, mut skipped) = (0, 0, 0);
|
let (mut clipped, mut clean, mut skipped) = (0, 0, 0);
|
||||||
for movie in movies {
|
for movie in movies {
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ fn main() {
|
|||||||
let entries = PakArchive::parse_toc(&stoc).expect("toc");
|
let entries = PakArchive::parse_toc(&stoc).expect("toc");
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"{:10} {:>6} {:>12} {:>12} {:>12} {:>10} {:>9} {}",
|
"{:10} {:>6} {:>12} {:>12} {:>12} {:>10} {:>9} note",
|
||||||
"movie", "id", "anchor", "pred(id-1)", "pred(before)", "span", "chosen", "note"
|
"movie", "id", "anchor", "pred(id-1)", "pred(before)", "span", "chosen"
|
||||||
);
|
);
|
||||||
for m in movie_manifest::parse(&manifest) {
|
for m in movie_manifest::parse(&manifest) {
|
||||||
let movie = m.movie;
|
let movie = m.movie;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ fn all_descriptors(buf: &[u8]) -> Vec<(usize, u32)> {
|
|||||||
let mut o = 0;
|
let mut o = 0;
|
||||||
while o <= end {
|
while o <= end {
|
||||||
let id = be(o);
|
let id = be(o);
|
||||||
if id >= 1 && id < ID_MAX && be(o + 4) == DESC_MARK && be(o + DESC_REPEAT) == id {
|
if (1..ID_MAX).contains(&id) && be(o + 4) == DESC_MARK && be(o + DESC_REPEAT) == id {
|
||||||
out.push((o, id));
|
out.push((o, id));
|
||||||
}
|
}
|
||||||
o += 4;
|
o += 4;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ fn all_descriptors(buf: &[u8]) -> Vec<(usize, u32)> {
|
|||||||
let mut o = 0;
|
let mut o = 0;
|
||||||
while o <= end {
|
while o <= end {
|
||||||
let id = be(o);
|
let id = be(o);
|
||||||
if id >= 1 && id < ID_MAX && be(o + 4) == DESC_MARK && be(o + DESC_REPEAT) == id {
|
if (1..ID_MAX).contains(&id) && be(o + 4) == DESC_MARK && be(o + DESC_REPEAT) == id {
|
||||||
out.push((o, id));
|
out.push((o, id));
|
||||||
}
|
}
|
||||||
o += 4;
|
o += 4;
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ use std::path::{Path, PathBuf};
|
|||||||
|
|
||||||
use sylpheed_formats::mesh::Xbg7Model;
|
use sylpheed_formats::mesh::Xbg7Model;
|
||||||
|
|
||||||
|
/// Every place one model name was seen: (span, verts, tris, container).
|
||||||
|
type Sightings = BTreeMap<String, Vec<([i64; 3], usize, usize, String)>>;
|
||||||
|
|
||||||
fn disc_root() -> Option<PathBuf> {
|
fn disc_root() -> Option<PathBuf> {
|
||||||
if let Ok(p) = std::env::var("SYLPHEED_DISC") {
|
if let Ok(p) = std::env::var("SYLPHEED_DISC") {
|
||||||
let p = PathBuf::from(p);
|
let p = PathBuf::from(p);
|
||||||
@@ -69,7 +72,7 @@ fn shared_resources_decode_identically_in_every_container() {
|
|||||||
files.sort();
|
files.sort();
|
||||||
|
|
||||||
// name -> (verts, tris) -> set of spans seen
|
// name -> (verts, tris) -> set of spans seen
|
||||||
let mut seen: BTreeMap<String, Vec<([i64; 3], usize, usize, String)>> = BTreeMap::new();
|
let mut seen: Sightings = BTreeMap::new();
|
||||||
for f in &files {
|
for f in &files {
|
||||||
let Ok(bytes) = std::fs::read(f) else {
|
let Ok(bytes) = std::fs::read(f) else {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ fn hero_ship_grouped_pool_decodes() {
|
|||||||
|
|
||||||
let mut agree = 0usize;
|
let mut agree = 0usize;
|
||||||
let mut counted = 0usize;
|
let mut counted = 0usize;
|
||||||
for tri in m.indices.chunks_exact(3) {
|
for tri in m.indices.as_chunks::<3>().0 {
|
||||||
let (a, b, c) = (tri[0] as usize, tri[1] as usize, tri[2] as usize);
|
let (a, b, c) = (tri[0] as usize, tri[1] as usize, tri[2] as usize);
|
||||||
let (pa, pb, pc) = (m.positions[a], m.positions[b], m.positions[c]);
|
let (pa, pb, pc) = (m.positions[a], m.positions[b], m.positions[c]);
|
||||||
let u = [pb[0] - pa[0], pb[1] - pa[1], pb[2] - pa[2]];
|
let u = [pb[0] - pa[0], pb[1] - pa[1], pb[2] - pa[2]];
|
||||||
@@ -478,7 +478,7 @@ fn stage_models_quality_audit() {
|
|||||||
hi[a] = hi[a].max(p[a]);
|
hi[a] = hi[a].max(p[a]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for tri in sub.indices.chunks_exact(3) {
|
for tri in sub.indices.as_chunks::<3>().0 {
|
||||||
let (a, b, c) = (tri[0] as usize, tri[1] as usize, tri[2] as usize);
|
let (a, b, c) = (tri[0] as usize, tri[1] as usize, tri[2] as usize);
|
||||||
if a >= sub.positions.len() || b >= sub.positions.len() || c >= sub.positions.len()
|
if a >= sub.positions.len() || b >= sub.positions.len() || c >= sub.positions.len()
|
||||||
{
|
{
|
||||||
@@ -567,7 +567,9 @@ fn decoded_index_runs_have_almost_no_degenerate_triangles() {
|
|||||||
for sm in &m.meshes {
|
for sm in &m.meshes {
|
||||||
let d = sm
|
let d = sm
|
||||||
.indices
|
.indices
|
||||||
.chunks_exact(3)
|
.as_chunks::<3>()
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
.filter(|t| t[0] == t[1] || t[1] == t[2] || t[0] == t[2])
|
.filter(|t| t[0] == t[1] || t[1] == t[2] || t[0] == t[2])
|
||||||
.count();
|
.count();
|
||||||
if d > 0 {
|
if d > 0 {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//! Real-disc test for the movie manifest → voice binding. Skipped without
|
//! Real-disc test for the movie manifest → voice binding. Skipped without
|
||||||
//! `SYLPHEED_DISC`.
|
//! `SYLPHEED_DISC`.
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use sylpheed_formats::movie_manifest;
|
use sylpheed_formats::movie_manifest;
|
||||||
use sylpheed_formats::slb::VoiceLang;
|
use sylpheed_formats::slb::VoiceLang;
|
||||||
@@ -13,7 +13,7 @@ fn disc_root() -> Option<PathBuf> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read the manifest + `eng\sounds.tbl` out of `tables.pak`.
|
/// Read the manifest + `eng\sounds.tbl` out of `tables.pak`.
|
||||||
fn load_manifest_and_sounds(root: &PathBuf) -> (Vec<u8>, Vec<u8>) {
|
fn load_manifest_and_sounds(root: &Path) -> (Vec<u8>, Vec<u8>) {
|
||||||
let pak = PakArchive::open(root.join("dat/tables.pak")).unwrap();
|
let pak = PakArchive::open(root.join("dat/tables.pak")).unwrap();
|
||||||
let manifest = pak
|
let manifest = pak
|
||||||
.entries()
|
.entries()
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ fn stage02_has_a_main_objective_for_each_phase() {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let text = TextIndex::build(&pak);
|
let text = TextIndex::build(&pak);
|
||||||
assert!(text.len() > 0, "text index is empty");
|
assert!(!text.is_empty(), "text index is empty");
|
||||||
|
|
||||||
for stage in ["S01", "S02"] {
|
for stage in ["S01", "S02"] {
|
||||||
for phase in 1..=3u32 {
|
for phase in 1..=3u32 {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Seek, SeekFrom};
|
use std::io::{Read, Seek, SeekFrom};
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use sylpheed_formats::hash::name_hash;
|
use sylpheed_formats::hash::name_hash;
|
||||||
use sylpheed_formats::slb::{self, VoiceLang};
|
use sylpheed_formats::slb::{self, VoiceLang};
|
||||||
@@ -15,7 +15,7 @@ fn disc_root() -> Option<PathBuf> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read `[off, off+size)` from `dat/sound.p00..` (segments concatenated).
|
/// Read `[off, off+size)` from `dat/sound.p00..` (segments concatenated).
|
||||||
fn read_range(root: &PathBuf, mut off: u64, size: usize) -> Vec<u8> {
|
fn read_range(root: &Path, mut off: u64, size: usize) -> Vec<u8> {
|
||||||
let mut out = Vec::with_capacity(size);
|
let mut out = Vec::with_capacity(size);
|
||||||
let mut need = size;
|
let mut need = size;
|
||||||
for i in 0..100u32 {
|
for i in 0..100u32 {
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ fn leading_data_offset_is_derived_not_assumed() {
|
|||||||
"{path}: leading stream is not a whole packet count"
|
"{path}: leading stream is not a whole packet count"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
got == slb::HEADERLESS_DATA_OFFSET || got > slb::HEADERLESS_DATA_OFFSET,
|
got >= slb::HEADERLESS_DATA_OFFSET,
|
||||||
"{path}: offsets below the old constant are unexplained"
|
"{path}: offsets below the old constant are unexplained"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,8 @@ async fn xpr_pipeline_over_disc_sample() {
|
|||||||
// Sanity: does the decoded data length match the descriptor
|
// Sanity: does the decoded data length match the descriptor
|
||||||
// dimensions (what the GPU upload will require)?
|
// dimensions (what the GPU upload will require)?
|
||||||
let bs = t.format.block_size() as u32;
|
let bs = t.format.block_size() as u32;
|
||||||
let bw = ((t.width + bs - 1) / bs).max(1) as usize;
|
let bw = t.width.div_ceil(bs).max(1) as usize;
|
||||||
let bh = ((t.height + bs - 1) / bs).max(1) as usize;
|
let bh = t.height.div_ceil(bs).max(1) as usize;
|
||||||
let need = bw * bh * t.format.bytes_per_block();
|
let need = bw * bh * t.format.bytes_per_block();
|
||||||
let size_ok = if need == t.data.len() {
|
let size_ok = if need == t.data.len() {
|
||||||
"ok"
|
"ok"
|
||||||
|
|||||||
@@ -202,8 +202,7 @@ fn forced_backdrops_are_full_screen_and_plentiful() {
|
|||||||
element.name
|
element.name
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
element.pivot_x * 2 >= b.design_w as u32
|
element.pivot_x * 2 >= b.design_w && element.pivot_y * 2 >= b.design_h,
|
||||||
&& element.pivot_y * 2 >= b.design_h as u32,
|
|
||||||
"{}: a quad that does not cover the screen cannot occlude it",
|
"{}: a quad that does not cover the screen cannot occlude it",
|
||||||
element.name
|
element.name
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -170,7 +170,13 @@ fn title_background_is_full_screen() {
|
|||||||
Some(&visible),
|
Some(&visible),
|
||||||
);
|
);
|
||||||
assert_eq!(screen.drawn, vec![base.index]);
|
assert_eq!(screen.drawn, vec![base.index]);
|
||||||
let uncovered = screen.rgba.chunks_exact(4).filter(|p| p[3] == 0).count();
|
let uncovered = screen
|
||||||
|
.rgba
|
||||||
|
.as_chunks::<4>()
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.filter(|p| p[3] == 0)
|
||||||
|
.count();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
uncovered,
|
uncovered,
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ fn the_derived_order_puts_primitives_last_and_that_wipes_screens() {
|
|||||||
};
|
};
|
||||||
let flatness = |c: &ui_layout::ComposedScreen| {
|
let flatness = |c: &ui_layout::ComposedScreen| {
|
||||||
let mut hist = std::collections::HashMap::<[u8; 3], usize>::new();
|
let mut hist = std::collections::HashMap::<[u8; 3], usize>::new();
|
||||||
for p in c.rgba.chunks_exact(4) {
|
for p in c.rgba.as_chunks::<4>().0 {
|
||||||
*hist.entry([p[0], p[1], p[2]]).or_default() += 1;
|
*hist.entry([p[0], p[1], p[2]]).or_default() += 1;
|
||||||
}
|
}
|
||||||
*hist.values().max().unwrap_or(&0) as f64 / (c.width * c.height) as f64
|
*hist.values().max().unwrap_or(&0) as f64 / (c.width * c.height) as f64
|
||||||
|
|||||||
Reference in New Issue
Block a user