re: test the port's black-backdrop predicate disc-wide -- exact locally, rare globally
sylpheed-port proposed that a screen declaring a full-screen .prm at t=0 with fade == 0xff000000 is standalone, and one without it is composited: 12/4 across their sixteen exported screens, every exception independently known to be composited. They asked for it against archives they do not have. That is my lane. CONTROL: the predicate reproduces their split exactly. GP_TITLE's sixteen bundles give 12 with and 4 without, the four without being entries 0, 1, 2, 3 -- build_00, build_01, press_start, press_start_jp -- and the element names match (pteff00.prm, palogo_eff0.prm, pgloading_eff00.prm). Independent derivation from the disc, not a re-run of their tool. DISC-WIDE it is rare: 76 of 965 screen builds, 7.9 %. GP_STAGE_CLEAR 4/4, GP_SYSTEM 2/2 and GP_TUTORIAL 2/2 are all-yes; GP_HANGAR_ARSENAL is 0 of 390, and GP_READY_ROOM, GP_OPTIONS, GP_PAUSE_MENU and GP_GAMEOVER are all zero. So it is not a general standalone/composited test. GP_OPTIONS and GP_PAUSE_MENU are screens a player plainly sees as screens and declare no backdrop; read as "composited" the rule would make 92 % of the game's screens composited, which the archives do not support. What it appears to separate is narrower: screens that BEGIN FROM BLACK from everything else. A pause menu over gameplay, a hangar over a 3D scene and a plate over a title all lack a backdrop without being the same kind of thing -- the negative class is heterogeneous, which is what a two-way rule cannot express. For the port: exact within GP_TITLE, so --black for those twelve is justified from the file rather than assumed; do not carry it into the four archives they have yet to export, where in three of them it classifies every screen alike. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
78
crates/sylpheed-formats/examples/black_backdrop_predicate.rs
Normal file
78
crates/sylpheed-formats/examples/black_backdrop_predicate.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
//! Does a screen declare its own OPAQUE BLACK backdrop? Disc-wide.
|
||||
//!
|
||||
//! `sylpheed-port` observed that the splash builds declare `palogo_eff0.prm` as a
|
||||
//! full-screen primitive at t=0 with `fade_argb 0xff000000` -- alpha 255 over RGB
|
||||
//! 000000 -- and turned it into a candidate predicate: a declared opaque-black
|
||||
//! backdrop separates STANDALONE screens from COMPOSITED ones. On their sixteen
|
||||
//! exported screens it splits 12 / 4, with all four exceptions independently known
|
||||
//! to be composited (the two `press_start` plates, and two loading builds that
|
||||
//! carry the `pgloading_*` set without its backdrop).
|
||||
//!
|
||||
//! That matters because the corpus previously told them "no content rule exists,
|
||||
//! take the entry index" -- correct for the question asked (recognise the splash),
|
||||
//! but this is a content rule for a different and useful question. They asked for
|
||||
//! it to be tested against an archive they do not have. This is that test.
|
||||
//!
|
||||
//! CONTROL: it must reproduce the 12/4 split on GP_TITLE's sixteen composable
|
||||
//! bundles before its disc-wide numbers mean anything.
|
||||
//!
|
||||
//! cargo run -p sylpheed-formats --example black_backdrop_predicate
|
||||
use sylpheed_formats::{pak::PakArchive, ui_layout};
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// A screen declares its own backdrop if some `.prm` primitive holds
|
||||
/// `fade == 0xff000000` at t = 0: full alpha over black.
|
||||
fn has_black_backdrop(b: &ui_layout::UiBuild) -> Option<String> {
|
||||
for el in &b.elements {
|
||||
if !el.name.ends_with(".prm") { continue }
|
||||
if let Some(k) = el.keyframes.iter().find(|k| k.time == Some(0)) {
|
||||
if k.fade == 0xff00_0000 { return Some(el.name.clone()) }
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let root = PathBuf::from(std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC"));
|
||||
|
||||
println!("== CONTROL: GP_TITLE's 16 composable bundles (port reports 12 with, 4 without)");
|
||||
let ar = PakArchive::open(root.join("dat/GP_TITLE.pak")).expect("GP_TITLE.pak");
|
||||
let (mut y, mut n) = (0, 0);
|
||||
for e in 0..16usize {
|
||||
let Ok(by) = ar.read(&ar.entries()[e]) else { continue };
|
||||
let Some(b) = ui_layout::parse_build(&by) else { continue };
|
||||
match has_black_backdrop(&b) {
|
||||
Some(nm) => { y += 1; println!(" entry {e:>2} YES {nm}") }
|
||||
None => { n += 1; println!(" entry {e:>2} no") }
|
||||
}
|
||||
}
|
||||
println!(" -> {y} with, {n} without\n");
|
||||
|
||||
println!("== DISC-WIDE, over every screen build");
|
||||
let mut paks: Vec<PathBuf> = std::fs::read_dir(root.join("dat")).expect("dat/")
|
||||
.filter_map(|e| e.ok().map(|e| e.path()))
|
||||
.filter(|p| p.extension().is_some_and(|x| x == "pak")).collect();
|
||||
paks.sort();
|
||||
let (mut tot, mut with) = (0usize, 0usize);
|
||||
for pak in &paks {
|
||||
let Ok(ar) = PakArchive::open(pak) else { continue };
|
||||
let name = pak.file_name().unwrap().to_string_lossy().to_string();
|
||||
let (mut t, mut w) = (0usize, 0usize);
|
||||
for e in ar.entries() {
|
||||
let Ok(by) = ar.read(e) else { continue };
|
||||
if !ui_layout::is_build(&by) { continue }
|
||||
let Some(b) = ui_layout::parse_build(&by) else { continue };
|
||||
t += 1;
|
||||
if has_black_backdrop(&b).is_some() { w += 1 }
|
||||
}
|
||||
if t > 0 {
|
||||
println!("{name:30} {w:4} / {t:<4} declare a black backdrop");
|
||||
std::io::stdout().flush().ok();
|
||||
}
|
||||
tot += t; with += w;
|
||||
}
|
||||
println!("\n{with} of {tot} screen builds disc-wide declare an opaque-black backdrop \
|
||||
({:.1} %)", 100.0 * with as f64 / tot as f64);
|
||||
println!("--- END ---");
|
||||
}
|
||||
55
docs/re/data/black-backdrop-predicate.txt
Normal file
55
docs/re/data/black-backdrop-predicate.txt
Normal file
@@ -0,0 +1,55 @@
|
||||
# Does a screen declare its own OPAQUE-BLACK backdrop? Disc-wide. 2026-08-30.
|
||||
# instrument: crates/sylpheed-formats/examples/black_backdrop_predicate.rs
|
||||
# predicate: some .prm element holds fade == 0xff000000 at t=0.
|
||||
#
|
||||
# sylpheed-port proposed this as a rule separating STANDALONE screens from
|
||||
# COMPOSITED ones, split 12/4 across their sixteen exported screens, and asked
|
||||
# for it to be tested against archives they do not have.
|
||||
#
|
||||
== CONTROL: GP_TITLE's 16 composable bundles (port reports 12 with, 4 without)
|
||||
entry 0 no
|
||||
entry 1 no
|
||||
entry 2 no
|
||||
entry 3 no
|
||||
entry 4 YES pteff00.prm
|
||||
entry 5 YES pteff00.prm
|
||||
entry 6 YES pteff00.prm
|
||||
entry 7 YES pteff00.prm
|
||||
entry 8 YES pteff00.prm
|
||||
entry 9 YES pteff00.prm
|
||||
entry 10 YES palogo_eff0.prm
|
||||
entry 11 YES palogo_eff0.prm
|
||||
entry 12 YES pgloading_eff00.prm
|
||||
entry 13 YES palogo_eff0.prm
|
||||
entry 14 YES palogo_eff0.prm
|
||||
entry 15 YES pgloading_eff00.prm
|
||||
-> 12 with, 4 without
|
||||
|
||||
== DISC-WIDE, over every screen build
|
||||
GP_BUNK.pak 6 / 8 declare a black backdrop
|
||||
GP_CHALLENGE.pak 6 / 78 declare a black backdrop
|
||||
GP_DEBRIEFING_PILOTLOG.pak 0 / 18 declare a black backdrop
|
||||
GP_DIALOG.pak 34 / 105 declare a black backdrop
|
||||
GP_GAMEOVER.pak 0 / 10 declare a black backdrop
|
||||
GP_HANGAR_ARSENAL.pak 0 / 390 declare a black backdrop
|
||||
GP_LEADERBOARD.pak 0 / 4 declare a black backdrop
|
||||
GP_MAIN_GAME_D2D.pak 0 / 18 declare a black backdrop
|
||||
GP_MAIN_GAME_E2D.pak 0 / 18 declare a black backdrop
|
||||
GP_MAIN_GAME_F2D.pak 0 / 18 declare a black backdrop
|
||||
GP_MAIN_GAME_I2D.pak 0 / 18 declare a black backdrop
|
||||
GP_MAIN_GAME_J2D.pak 0 / 18 declare a black backdrop
|
||||
GP_MAIN_GAME_S2D.pak 0 / 18 declare a black backdrop
|
||||
GP_MISSION_LOG.pak 0 / 4 declare a black backdrop
|
||||
GP_MISSION_SELECT.pak 2 / 66 declare a black backdrop
|
||||
GP_MOVIE_THEATER.pak 2 / 56 declare a black backdrop
|
||||
GP_OPTIONS.pak 0 / 14 declare a black backdrop
|
||||
GP_PAUSE_MENU.pak 0 / 6 declare a black backdrop
|
||||
GP_READY_ROOM.pak 0 / 60 declare a black backdrop
|
||||
GP_SAVE_LOAD.pak 10 / 18 declare a black backdrop
|
||||
GP_STAGE_CLEAR.pak 4 / 4 declare a black backdrop
|
||||
GP_SYSTEM.pak 2 / 2 declare a black backdrop
|
||||
GP_TITLE.pak 8 / 12 declare a black backdrop
|
||||
GP_TUTORIAL.pak 2 / 2 declare a black backdrop
|
||||
|
||||
76 of 965 screen builds disc-wide declare an opaque-black backdrop (7.9 %)
|
||||
--- END ---
|
||||
@@ -472,3 +472,45 @@ cargo run -p sylpheed-formats --example prm_forced_first
|
||||
cargo run -p sylpheed-formats --example prm_occlusion_check
|
||||
SYLPHEED_DISC=/disc cargo test -p sylpheed-formats --test ui_forced_backdrop_disc
|
||||
```
|
||||
|
||||
|
||||
## 🟡 The opaque-black backdrop as a PREDICATE — sound where it is used, not general
|
||||
|
||||
`sylpheed-port` turned the splash's `palogo_eff0` into a candidate rule: *a screen
|
||||
declaring a full-screen `.prm` at `t=0` with `fade == 0xff000000` is **standalone**;
|
||||
one without it is **composited***. On their sixteen exported screens it splits 12/4
|
||||
with every exception independently known to be composited. They asked for it
|
||||
against archives they do not have. Tested:
|
||||
[`data/black-backdrop-predicate.txt`](../data/black-backdrop-predicate.txt).
|
||||
|
||||
✅ **The control reproduces their split exactly** — `GP_TITLE`'s sixteen bundles
|
||||
give 12 with and 4 without, and the four without are entries **0, 1, 2, 3**:
|
||||
`build_00`, `build_01`, `press_start`, `press_start_jp`. Element names match too
|
||||
(`pteff00.prm`, `palogo_eff0.prm`, `pgloading_eff00.prm`).
|
||||
|
||||
🔴 **Disc-wide it is rare: 76 of 965 screen builds, 7.9 %.**
|
||||
|
||||
| archive | with / total |
|
||||
|---|---|
|
||||
| `GP_STAGE_CLEAR`, `GP_SYSTEM`, `GP_TUTORIAL` | 4/4, 2/2, 2/2 — **all** |
|
||||
| `GP_SAVE_LOAD` | 10/18 |
|
||||
| `GP_DIALOG` | 34/105 |
|
||||
| `GP_HANGAR_ARSENAL` | **0 / 390** |
|
||||
| `GP_READY_ROOM` | 0/60 · `GP_OPTIONS` 0/14 · `GP_PAUSE_MENU` 0/6 · `GP_GAMEOVER` 0/10 |
|
||||
|
||||
⚠️ **So it is not a general standalone/composited test.** `GP_OPTIONS` and
|
||||
`GP_PAUSE_MENU` are screens a player plainly sees as screens, and they declare no
|
||||
backdrop; `GP_HANGAR_ARSENAL` declares none across **390** builds. Read as
|
||||
"composited", that would make 92 % of the game's screens composited, which the
|
||||
archives do not support.
|
||||
|
||||
🟡 **What it does appear to separate is narrower and still useful: screens that
|
||||
begin from BLACK from everything else.** A pause menu over gameplay, a hangar over
|
||||
a 3D scene and a plate over a title all legitimately lack a black backdrop, but
|
||||
they are not the same kind of thing — the negative class is **heterogeneous**, and
|
||||
that is exactly what a two-way rule cannot express.
|
||||
|
||||
📌 **For the port: keep using it where you found it.** Within `GP_TITLE` it is
|
||||
exact, and `--black` for those twelve is justified from the file rather than
|
||||
assumed. Do **not** carry it into the four archives you have yet to export — in
|
||||
three of them it would classify every screen the same way.
|
||||
|
||||
Reference in New Issue
Block a user