re: placement X/Y are SIGNED, the tail word is time, and the resting pose is max-dwell
Dumping the remaining Arsenal components turned up placements reading as 4294966780 and 4294966856 -- negative as i32 (-516, -440). X and Y are signed; off-screen animation starts are negative, and read as unsigned a reimplementation would draw them four billion pixels off. The raw region then showed the rest of it. The trailing word is a TIME, and a group is an in -> hold -> out animation: prselect_win1 runs t=4:-516 -> 6:-71 -> 7:81 -> 8:127 -> 23:134 -> 24:134 -> 25:127 -> 27:81 -> 31:-71 -> 1:-516. So NEITHER the first nor the last keyframe is where the element sits -- both are off-screen. The resting position is the max-dwell keyframe, (127,155)..(134,155) here, which is where the weapon-list panel actually appears. This corrects my own note from earlier today, which reported "final=" positions. Static elements were unaffected (the pause menu's buttons have identical keyframes) but animated ones were misread. screen_layout.rs now reports the max-dwell pose plus the full timeline, and both captures are regenerated. Also seen while dumping: kind 0x2, and a .sbo child (scrollbar) parented to the list window. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -54,7 +54,8 @@ fn main() {
|
||||
// Placement region: groups of (u32 element index, u32 keyframe count) then
|
||||
// `count` 40-byte keyframes; the X/Y sit 12 bytes into the scale/tint block.
|
||||
let mut pos = 0x20 + count * 60;
|
||||
let mut placements: Vec<Vec<(u32, u32)>> = vec![Vec::new(); count];
|
||||
// X/Y are SIGNED: off-screen animation starts are negative (e.g. -516).
|
||||
let mut placements: Vec<Vec<(i32, i32, u32)>> = vec![Vec::new(); count];
|
||||
for _ in 0..count {
|
||||
if pos + 8 > bytes.len() { break }
|
||||
let idx = be32(&bytes, pos) as usize;
|
||||
@@ -65,7 +66,7 @@ fn main() {
|
||||
for k in 0..frames {
|
||||
let blk = first + k * 40;
|
||||
if blk + 20 > bytes.len() { break }
|
||||
group.push((be32(&bytes, blk + 12), be32(&bytes, blk + 16)));
|
||||
group.push((be32(&bytes, blk + 12) as i32, be32(&bytes, blk + 16) as i32, be32(&bytes, blk + 20)));
|
||||
}
|
||||
placements[idx] = group;
|
||||
pos = first + frames * 40 - 20;
|
||||
@@ -76,10 +77,25 @@ fn main() {
|
||||
for i in 0..count {
|
||||
let (parent, kind, px, py) = meta[i];
|
||||
let p = &placements[i];
|
||||
let shown = match (p.first(), p.last()) {
|
||||
(Some(f), Some(l)) if p.len() > 1 && f != l => format!("{:?} → {:?}", f, l),
|
||||
(Some(f), _) => format!("{:?}", f),
|
||||
_ => "—".into(),
|
||||
// A group is an in → hold → out animation, so neither the first nor the
|
||||
// last keyframe is where the element sits: report the MAX-DWELL one
|
||||
// (longest gap to the next keyframe's time).
|
||||
let shown = if p.is_empty() {
|
||||
"—".into()
|
||||
} else if p.len() == 1 {
|
||||
format!("({},{})", p[0].0, p[0].1)
|
||||
} else {
|
||||
let mut best = (0usize, 0u32);
|
||||
for k in 0..p.len() - 1 {
|
||||
let d = p[k + 1].2.saturating_sub(p[k].2);
|
||||
if d > best.1 { best = (k, d) }
|
||||
}
|
||||
let r = p[best.0];
|
||||
format!(
|
||||
"rest ({},{}) t={}..{} [{}]",
|
||||
r.0, r.1, r.2, p[best.0 + 1].2,
|
||||
p.iter().map(|(x, y, t)| format!("{t}:{x},{y}")).collect::<Vec<_>>().join(" ")
|
||||
)
|
||||
};
|
||||
println!(
|
||||
"{:<3} {:<30} {:>7} {:>8} {:>12} {:>4} {}",
|
||||
|
||||
@@ -1,25 +1,50 @@
|
||||
=== eng\prmain_scr.prt ===
|
||||
23 elements
|
||||
# element parent kind pivot kf placement
|
||||
0 preff01.t32 - 0x0 (164,156) 5 (256, 214)
|
||||
1 preff02.t32 - 0x0 (155,175) 7 (305, 240)
|
||||
2 preff03.t32 - 0x0 (155,175) 7 (225, 150)
|
||||
3 preff04.t32 - 0x0 (247,237) 6 (173, 133)
|
||||
4 prwinbase.t32 - 0x0 (136,130) 5 (284, 240)
|
||||
5 prbtn1.rat - 0x3002 (28,14) 5 (242, 166)
|
||||
6 prbtn2.rat - 0x3002 (43,14) 5 (242, 220)
|
||||
7 prbtn3.rat - 0x3002 (58,14) 5 (242, 276)
|
||||
8 prbtn4.rat - 0x3002 (89,14) 5 (242, 331)
|
||||
9 prbtn5.rat - 0x3002 (89,14) 5 (242, 385)
|
||||
10 prbtn6.rat - 0x3002 (104,14) 5 (242, 441)
|
||||
11 prbtn7.rat - 0x3002 (58,14) 5 (242, 496)
|
||||
12 prbtn8.rat - 0x3002 (30,14) 5 (242, 551)
|
||||
13 prexp1.t32 - 0x0 (277,30) 8 (726, 143) → (1286, 143)
|
||||
14 prexp1a.t32 13 0x1 (277,30) 3 (1126, 143)
|
||||
15 prexp3.t32 - 0x0 (205,5) 5 (726, 381)
|
||||
16 prmsg.t32 - 0x0 (330,19) 5 (151, 645)
|
||||
17 prexp3.t32 - 0x4 (205,5) 5 (726, 415)
|
||||
18 prexp3.t32 - 0x4 (205,5) 5 (726, 449)
|
||||
19 prexp3.t32 - 0x4 (205,5) 5 (726, 483)
|
||||
20 prexp3.t32 - 0x4 (205,5) 5 (726, 517)
|
||||
21 prexp3.t32 - 0x4 (205,5) 5 (726, 551)
|
||||
22 prexp3.t32 - 0x4 (205,5) 5 (726, 585)
|
||||
0 preff01.t32 - 0x0 (164,156) 5 rest (256,214) t=6..22 [6:256,214 22:256,214 31:256,214 42:256,214 1:256,214]
|
||||
1 preff02.t32 - 0x0 (155,175) 7 rest (156,121) t=8..37 [4:305,240 6:193,150 7:165,128 8:156,121 37:155,120 44:155,120 2:305,240]
|
||||
2 preff03.t32 - 0x0 (155,175) 7 rest (374,269) t=8..37 [4:225,150 6:337,240 7:365,262 8:374,269 37:375,270 44:375,270 3:225,150]
|
||||
3 preff04.t32 - 0x0 (247,237) 6 rest (173,133) t=8..37 [4:173,133 6:173,133 8:173,133 37:173,133 44:173,133 4:173,133]
|
||||
4 prwinbase.t32 - 0x0 (136,130) 5 rest (284,240) t=14..35 [6:284,240 14:284,240 35:284,240 43:284,240 5:284,240]
|
||||
5 prbtn1.rat - 0x3002 (28,14) 5 rest (242,166) t=16..33 [10:242,166 16:242,166 33:242,166 37:242,166 6:242,166]
|
||||
6 prbtn2.rat - 0x3002 (43,14) 5 rest (242,220) t=17..33 [11:242,220 17:242,220 33:242,220 37:242,220 7:242,220]
|
||||
7 prbtn3.rat - 0x3002 (58,14) 5 rest (242,276) t=18..33 [12:242,276 18:242,276 33:242,276 37:242,276 8:242,276]
|
||||
8 prbtn4.rat - 0x3002 (89,14) 5 rest (242,331) t=19..33 [13:242,331 19:242,331 33:242,331 37:242,331 9:242,331]
|
||||
9 prbtn5.rat - 0x3002 (89,14) 5 rest (242,385) t=20..33 [14:242,385 20:242,385 33:242,385 37:242,385 10:242,385]
|
||||
10 prbtn6.rat - 0x3002 (104,14) 5 rest (242,441) t=21..33 [15:242,441 21:242,441 33:242,441 37:242,441 11:242,441]
|
||||
11 prbtn7.rat - 0x3002 (58,14) 5 rest (242,496) t=22..33 [16:242,496 22:242,496 33:242,496 37:242,496 12:242,496]
|
||||
12 prbtn8.rat - 0x3002 (30,14) 5 rest (242,551) t=23..33 [17:242,551 23:242,551 33:242,551 37:242,551 13:242,551]
|
||||
13 prexp1.t32 - 0x0 (277,30) 8 rest (726,143) t=31..37 [21:726,143 25:1286,143 27:866,143 28:756,143 29:731,143 31:726,143 37:726,143 14:1286,143]
|
||||
14 prexp1a.t32 13 0x1 (277,30) 3 rest (1126,143) t=31..37 [31:1126,143 37:1126,143 15:1126,143]
|
||||
15 prexp3.t32 - 0x0 (205,5) 5 rest (726,381) t=10..29 [10:726,381 29:726,381 31:726,381 39:726,381 16:726,381]
|
||||
16 prmsg.t32 - 0x0 (330,19) 5 rest (151,645) t=21..29 [21:151,645 29:151,645 31:151,645 37:151,645 17:151,645]
|
||||
17 prexp3.t32 - 0x4 (205,5) 5 rest (726,415) t=10..29 [10:726,415 29:726,415 31:726,415 39:726,415 18:726,415]
|
||||
18 prexp3.t32 - 0x4 (205,5) 5 rest (726,449) t=10..29 [10:726,449 29:726,449 31:726,449 39:726,449 19:726,449]
|
||||
19 prexp3.t32 - 0x4 (205,5) 5 rest (726,483) t=10..29 [10:726,483 29:726,483 31:726,483 39:726,483 20:726,483]
|
||||
20 prexp3.t32 - 0x4 (205,5) 5 rest (726,517) t=10..29 [10:726,517 29:726,517 31:726,517 39:726,517 21:726,517]
|
||||
21 prexp3.t32 - 0x4 (205,5) 5 rest (726,551) t=10..29 [10:726,551 29:726,551 31:726,551 39:726,551 22:726,551]
|
||||
22 prexp3.t32 - 0x4 (205,5) 5 rest (726,585) t=39..1869640736 [10:726,585 29:726,585 31:726,585 39:726,585 1869640736:726,585]
|
||||
=== eng\prselect_scr.prt ===
|
||||
8 elements
|
||||
# element parent kind pivot kf placement
|
||||
0 prselect_win1.t32 - 0x0 (256,200) 10 rest (127,155) t=8..23 [4:-516,155 6:-71,155 7:81,155 8:127,155 23:134,155 24:134,155 25:127,155 27:81,155 31:-71,155 1:-516,155]
|
||||
1 prselect_win2.t32 0 0x1 (256,200) 1 (135,560)
|
||||
2 prselect_win1eff.t32 0 0x1 (256,200) 5 rest (71,92) t=2..14 [2:71,92 14:71,92 21:71,92 27:71,92 3:71,92]
|
||||
3 prselect_win2eff.t32 0 0x1 (256,200) 5 rest (71,499) t=2..14 [2:71,499 14:71,499 21:71,499 27:71,499 4:71,499]
|
||||
4 prselect_sbar.sbo 0 0x1 (256,200) 1 (614,172)
|
||||
5 prselect_type_line.t32 - 0x0 (260,24) 5 rest (123,142) t=14..21 [8:123,142 14:123,142 21:123,142 25:123,142 6:123,142]
|
||||
6 prselect_msg.t32 - 0x0 (468,19) 5 rest (151,645) t=11..19 [11:151,645 19:151,645 21:151,645 27:151,645 7:151,645]
|
||||
7 prselect_msgbtn1.t32 - 0x2 (128,19) 5 rest (809,645) t=27..1869640736 [11:809,645 19:809,645 21:809,645 27:809,645 1869640736:809,645]
|
||||
=== eng\prselect_win3.prt ===
|
||||
2 elements
|
||||
# element parent kind pivot kf placement
|
||||
0 prselect_win3.t32 - 0x0 (245,300) 4 rest (704,39) t=10..16 [8:704,39 10:704,39 16:704,39 1:704,39]
|
||||
1 prselect_win3eff.t32 - 0x0 (309,352) 4 rest (640,0) t=16..1869640736 [8:640,0 10:640,0 16:640,0 1869640736:640,0]
|
||||
=== eng\prtitle.prt ===
|
||||
5 elements
|
||||
# element parent kind pivot kf placement
|
||||
0 preff11.t32 - 0x0 (221,6) 6 rest (-160,82) t=16..35 [12:-440,82 14:-440,82 16:-160,82 35:0,82 41:0,82 1:-440,82]
|
||||
1 preff12.t32 - 0x0 (75,3) 5 rest (0,72) t=20..34 [14:0,72 20:0,72 34:0,72 38:0,72 2:0,72]
|
||||
2 preff13.t32 - 0x0 (53,3) 5 rest (407,78) t=22..33 [16:407,78 22:407,78 33:407,78 37:407,78 3:407,78]
|
||||
3 preff14.t32 - 0x0 (52,3) 5 rest (427,68) t=24..32 [18:427,68 24:427,68 32:427,68 36:427,68 4:427,68]
|
||||
4 prtitle.t32 - 0x0 (94,35) 7 rest (162,26) t=37..1869640736 [20:142,26 23:142,26 25:157,26 26:161,26 31:162,26 37:162,26 1869640736:142,26]
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
11 elements
|
||||
# element parent kind pivot kf placement
|
||||
0 pgp_ttrl_eff11.t32 - 0x0 (34,33) 7 (603, 121) → (493, 121)
|
||||
1 pgp_ttrl_eff12.t32 - 0x0 (34,33) 7 (609, 121) → (719, 121)
|
||||
2 pgp_ttrl_eff10.t32 - 0x0 (204,60) 5 (436, 94)
|
||||
3 pgp_ttrl_eff22.t32 - 0x0 (133,130) 5 (480, 225) → (490, 225)
|
||||
4 pgp_ttrl_eff23.t32 - 0x0 (138,130) 5 (524, 271) → (514, 271)
|
||||
5 pgp_ttrl_eff21.t32 - 0x0 (214,180) 5 (426, 198)
|
||||
6 pgp_ttrl_title.rat - 0x0 (101,36) 6 (540, 119)
|
||||
7 pgp_ttrl_btn10.rat - 0x3002 (43,21) 5 (546, 288)
|
||||
8 pgp_ttrl_btn11.rat - 0x3002 (86,22) 5 (546, 358)
|
||||
9 pgp_ttrl_btn12.rat - 0x3002 (110,21) 5 (546, 428)
|
||||
10 pgp_ttrl_msg.t32 - 0x0 (190,19) 5 (451, 545)
|
||||
0 pgp_ttrl_eff11.t32 - 0x0 (34,33) 7 rest (470,121) t=9..25 [3:603,121 6:603,121 8:503,121 9:470,121 25:463,121 30:463,121 1:493,121]
|
||||
1 pgp_ttrl_eff12.t32 - 0x0 (34,33) 7 rest (742,121) t=9..25 [3:609,121 6:609,121 8:709,121 9:742,121 25:749,121 30:749,121 2:719,121]
|
||||
2 pgp_ttrl_eff10.t32 - 0x0 (204,60) 5 rest (436,94) t=14..23 [8:436,94 14:436,94 23:436,94 30:436,94 3:436,94]
|
||||
3 pgp_ttrl_eff22.t32 - 0x0 (133,130) 5 rest (480,225) t=11..25 [5:480,225 11:480,225 25:460,225 30:460,225 4:490,225]
|
||||
4 pgp_ttrl_eff23.t32 - 0x0 (138,130) 5 rest (524,271) t=11..25 [5:524,271 11:524,271 25:544,271 30:544,271 5:514,271]
|
||||
5 pgp_ttrl_eff21.t32 - 0x0 (214,180) 5 rest (426,198) t=9..21 [9:426,198 21:426,198 23:426,198 30:426,198 6:426,198]
|
||||
6 pgp_ttrl_title.rat - 0x0 (101,36) 6 rest (540,119) t=13..23 [5:540,119 13:540,119 23:540,119 28:540,119 30:540,119 7:540,119]
|
||||
7 pgp_ttrl_btn10.rat - 0x3002 (43,21) 5 rest (546,288) t=15..23 [9:546,288 15:546,288 23:546,288 26:546,288 8:546,288]
|
||||
8 pgp_ttrl_btn11.rat - 0x3002 (86,22) 5 rest (546,358) t=11..17 [11:546,358 17:546,358 23:546,358 26:546,358 9:546,358]
|
||||
9 pgp_ttrl_btn12.rat - 0x3002 (110,21) 5 rest (546,428) t=13..19 [13:546,428 19:546,428 23:546,428 26:546,428 10:546,428]
|
||||
10 pgp_ttrl_msg.t32 - 0x0 (190,19) 5 rest (451,545) t=28..1869640736 [16:451,545 21:451,545 23:451,545 28:451,545 1869640736:451,545]
|
||||
|
||||
@@ -202,17 +202,33 @@ recording them because a static-only reading would have shipped them:
|
||||
```
|
||||
group header: u32 element index (0,1,2… — the correspondence is stated, not inferred)
|
||||
u32 keyframe count
|
||||
then `count` keyframes, 40 bytes apart, each holding the familiar block:
|
||||
then `count` keyframes, 40 bytes apart, each holding:
|
||||
u32 scale X = 100 u32 scale Y = 100
|
||||
u32 tint = 0xffffffff
|
||||
u32 X u32 Y (+ a trailing time field)
|
||||
i32 X i32 Y ← SIGNED
|
||||
u32 time u32 flags/terminator
|
||||
```
|
||||
|
||||
**Three things here are easy to get wrong, and were:**
|
||||
|
||||
- **X and Y are signed.** Off-screen animation starts are negative — the Arsenal's
|
||||
weapon-list window begins at **X = −516**. Read as unsigned it is 4 294 966 780,
|
||||
which a naïve implementation would happily draw four billion pixels to the right.
|
||||
- **The trailing word is a time**, and a group is an **in → hold → out**
|
||||
animation. `prselect_win1` runs `t=4:−516 → 6:−71 → 7:81 → 8:127 → 23:134 →
|
||||
24:134 → 25:127 → 27:81 → 31:−71 → 1:−516`.
|
||||
- **So neither the first nor the last keyframe is where the element sits.** Both
|
||||
are off-screen for an animated element. The resting position is the
|
||||
**max-dwell** keyframe — the one with the longest gap to the next time — which
|
||||
for that window is **(127,155)…(134,155)**, matching where the list panel
|
||||
actually appears. `screen_layout.rs` reports that, not `final`.
|
||||
|
||||
For the tutorial pause bundle this yields 11 groups for 11 elements, and every
|
||||
group's header index and count match the blocks actually present. The values are
|
||||
self-evidently right: the three menu buttons sit at X=546, **70 px apart**
|
||||
(288 / 358 / 428), the title at (540,119), the message at (451,545), and the
|
||||
`eff*` sprites carry multi-position fly-ins.
|
||||
(288 / 358 / 428) — static, every keyframe identical, which is why their reading
|
||||
was unaffected by the first/last mistake above — the title at (540,119), the
|
||||
message at (451,545), and the `eff*` sprites carry multi-position fly-ins.
|
||||
|
||||
**Cross-checked against the records themselves:** `pgp_ttrl_btn10.rat` places its
|
||||
sprite at **(546,288)** — identical to its inline group. So the inline region is
|
||||
|
||||
Reference in New Issue
Block a user