port: F6 -- adopt the sweep onset as a measured RATIO, and fix the guard that disabled it

Onset: 0.500 of (title first visible element -> plate onset), measured by the
Decoder as 0.489 and 0.507 across two independent captures, 3.7% apart. A RATIO,
which is the point -- it needs no clock, and every unit-valued figure from those
captures has been withdrawn: the rate because frames are presents (1168 vs 600
for the same animation), the '+40 units' because its conversion put
title-start->plate at 75 units where the declared data puts the plate at 238, a
3.2x conflict that is still open and is F4's.

Resolved against THIS export: 0.500 x (214 - 0) = 107.0 units.
tools/port/check-leaf-onset recomputes it and fails if a re-timing moves the
anchors; it has a selftest in both directions and is in check-all.

🔴 AND THE ADOPTION WAS A NO-OP UNTIL THIS COMMIT. leaf_clock() read
'if start < 0.0 OR rate <= 0.0: return screen_units', so when the withdrawn rate
went back to null the adopted OFFSET stopped applying too -- silently, while
authored/rendering.json still stated it. The two fields are independent now.

It was caught only because the offset was re-verified by PROBING THE RENDERER
instead of re-reading the file I had just edited. Both my earlier verifications
of this feature passed while it did nothing: one compared frames that were all
being forced to the same pose, the other ran when both fields happened to be set.

Verified, pre-registered before running, via --probe-leaf:
  title u=236 -> leaf_t 129.0, x -123   (predicted 129, -123)
  title u=400 -> leaf_t 293.0, x  533   (predicted 293,  533)

Effect: at the plate's arrival the sweep sits at x=-123, just entering the frame,
where before it was at x=305, well across it.
This commit is contained in:
Sylpheed port agent
2026-09-02 19:34:42 +00:00
parent a27e609672
commit af10a2ec3c
5 changed files with 113 additions and 28 deletions

View File

@@ -366,6 +366,9 @@ func _ready() -> void:
view.leaf_time_units = float(args["leaf-time"]) * view.units_per_second
view.queue_redraw()
if args.has("probe-leaf"):
view._probe_leaf = true
if args.has("time"):
_frozen = true
# An explicit instant beats the settle instant -- see `ScreenView.frozen`.

View File

@@ -201,6 +201,11 @@ var leaf_time_units: float = -1.0
##
## `leaf_time_units` above is a different thing -- an ABSOLUTE override for the
## `--leaf-time` diagnostic, which pins a pose and ignores both of these.
## `--probe-leaf` only: print each leaf's clock and pose as it is drawn. A
## diagnostic, because "the authored file says 107" and "the renderer applies
## 107" are different claims and this port has confused them once already.
var _probe_leaf := false
var leaf_start_units: float = -1.0
var leaf_rate: float = -1.0
@@ -213,9 +218,20 @@ var leaf_rate: float = -1.0
## start is visually indistinguishable from not drawing, without disturbing the
## parent-fallback path that `_draw_leaf` returns into.
func leaf_clock(screen_units: float) -> float:
if leaf_start_units < 0.0 or leaf_rate <= 0.0:
# 🔴 THE TWO ARE INDEPENDENT, and an earlier version required BOTH. It read
# `if start < 0.0 OR rate <= 0.0: return screen_units`, so when the measured
# rate was withdrawn and set back to null, the ADOPTED OFFSET stopped being
# applied too -- silently, with the authored file still stating it. It was
# caught only because the offset was re-verified by probing the renderer
# rather than by re-reading the data that had just been edited.
if leaf_start_units < 0.0 and leaf_rate <= 0.0:
return screen_units
return maxf(0.0, (screen_units - leaf_start_units) * leaf_rate)
var t := screen_units
if leaf_start_units >= 0.0:
t -= leaf_start_units
if leaf_rate > 0.0:
t *= leaf_rate
return maxf(0.0, t)
## While true the screen holds at `rest` and never plays its exit. The
## sequencer clears it to send the screen away.
@@ -723,6 +739,8 @@ func _draw_leaf(element: Dictionary) -> bool:
if span > 0.0:
t = fposmod(t, span)
var pose := pose_at(fe, t)
if _probe_leaf:
print("PROBE u=%.1f leaf_t=%.1f x=%s" % [time_units, t, pose.get("pos", [])])
holding = was
# 🔴 A SCALE-0 LEAF MUST NOT CLAIM THE DRAW. The Decoder hit this in its own
# renderer: its leaf branch marked the element drawn unconditionally, but