formats: a UI element scales about its pivot, not its keyframe corner
The compositor read a keyframe as `top-left = (X,Y)`, `size = decoded · scale` and ignored the declared pivot. That is right at 100 %, which is every element the format was ever checked against — the pause menu, the ARSENAL chip ruler — and wrong for every element that is scaled. Measured against a framebuffer capture of Canary on the title screen. `GP_TITLE.pak` build 7 element 13 is `ptbase2.t32`: 640x360, pivot (320,180), one keyframe at (320,180) with scale 200 %. From the corner that is a 1280x720 rect at 320..1600 x 180..900 — a quarter-screen slab with the top-left quadrant bare. Anchored at the pivot it is (0,0)..(1280,720), and the capture shows the background art reaching all four edges. Normalised cross-correlation of the composite against the capture, searched over +-40 px, peaks at (0,0): 0.90 on the planet limb, 0.72 on the lower-left ship. `ptcopyright.t32` calibrates the other half: unscaled, 694x20 at (293,655), and the capture's glyph run is x 295..986 / y 700..718 once the 45 px of window chrome is taken off. So the keyframe really is the top-left at 1:1. Disc-wide this moves 865 of 5 130 resting placements. The pause menu's own `pgpeff01` glow stops hanging off the menu frame to the bottom-right and centres on it. `ComposeOptions::backdrop` comes with it: the default dim slate stands in for the PRMD dim-quad behind an in-mission screen, but comparing against a framebuffer needs the black the game actually composites over, so `screen render --black` can ask for it.
This commit is contained in:
@@ -153,6 +153,11 @@ enum ScreenCommands {
|
||||
/// Draw `loop*` sprite animations
|
||||
#[arg(long)]
|
||||
animated: bool,
|
||||
/// Start the canvas black instead of the default dim slate — what the
|
||||
/// game composites over on a screen carrying its own background, and so
|
||||
/// what a framebuffer capture must be compared against.
|
||||
#[arg(long)]
|
||||
black: bool,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -297,8 +302,15 @@ async fn main() -> Result<()> {
|
||||
Commands::Screen { cmd } => match cmd {
|
||||
ScreenCommands::List { pak } => cmd_screen_list(&pak),
|
||||
ScreenCommands::Info { pak, build } => cmd_screen_info(&pak, build),
|
||||
ScreenCommands::Render { pak, output, build, focus, animated } => {
|
||||
cmd_screen_render(&pak, &output, build, focus, animated)
|
||||
ScreenCommands::Render {
|
||||
pak,
|
||||
output,
|
||||
build,
|
||||
focus,
|
||||
animated,
|
||||
black,
|
||||
} => {
|
||||
cmd_screen_render(&pak, &output, build, focus, animated, black)
|
||||
}
|
||||
},
|
||||
Commands::Save { cmd } => match cmd {
|
||||
@@ -433,6 +445,7 @@ fn cmd_screen_render(
|
||||
want: Option<usize>,
|
||||
focus: bool,
|
||||
animated: bool,
|
||||
black: bool,
|
||||
) -> Result<()> {
|
||||
use sylpheed_formats::ui_layout::{self, ComposeOptions};
|
||||
let builds = screen_builds(pak)?;
|
||||
@@ -445,6 +458,11 @@ fn cmd_screen_render(
|
||||
ComposeOptions {
|
||||
include_focus: focus,
|
||||
include_animated: animated,
|
||||
backdrop: if black {
|
||||
[0, 0, 0, 255]
|
||||
} else {
|
||||
ComposeOptions::default().backdrop
|
||||
},
|
||||
},
|
||||
None,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user