diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index 26f7ee3..698872e 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -28,11 +28,11 @@ authored version can be deleted. | | Question | State | Answer / link | |---|---|---|---| | Q1 | keyframe time unit + ramp shape | βœ… answered | ramp is **linear**; the clock advances **2 units per rendered frame**; working conversion **1 unit = 1/60 s** β€” [`ui-keyframe-time-unit.md`](../re/ui-keyframe-time-unit.md) | -| Q2 | which build is which screen state | 🟑 partial | build 4 title, 5 main menu, 6/8/9 submenus, `palogo` splash β€” unconfirmed against captures | +| Q2 | which build is which screen state | βœ… answered | `GP_TITLE` is **8 screens shipped twice, EN/JP**: 4/7 title art, 2/3 the `PRESS β’Ά` plate, 5/8 main menu, 6/9 `EXTRAS`, 0/1 and 10/11 two unidentified `DELTASABER` plates β€” [`ui-title-build-map.md`](../re/ui-title-build-map.md) | | Q3 | paint order for the six screens | ❔ open | runtime-solved only; declaration table is refuted | | Q4 | button β†’ GamePart | ❔ open | labels are baked into sprites | | Q5 | navigation semantics | ❔ open | | -| Q6 | boot sequence + what drives it | 🟑 partial | order observed; the driver is not decoded | +| Q6 | boot sequence + what drives it | 🟑 partial | order observed, and the **attract cycle is timed**: ~8–10 s idle on the title β†’ fade to black β†’ ~85 s of video β†’ title again, plate and all. The driver is still not decoded | | Q7 | transitions | ❔ open | | | Q8 | menu audio bindings | ❔ open | cue table complete, event binding is not | | Q9 | video binding + playback rules | 🟑 partial | `ADV.wmv` is the boot intro; new-game intro unidentified | @@ -41,10 +41,19 @@ authored version can be deleted. ## Already settled β€” the port can rely on these today -* **`GP_TITLE.pak` is the whole title-side tree.** Build 4 is the title with the - animating wordmarks, build 5 the five-button main menu, builds 6/8/9 are - submenus, and the developer splash is the `palogo` bundle in the same archive. - βœ… decoded (enumeration), 🟑 the state labels are not yet capture-confirmed. +* **`GP_TITLE.pak` is eight screens, each shipped twice β€” English and Japanese.** + Build 4 is the English title art and 7 its Japanese twin; **2/3 are the + `PRESS β’Ά BUTTON` plate, a build of their own** composited over the title and + faded in a beat later; 5/8 are the five-button main menu; 6/9 are the `EXTRAS` + submenu β€” the **only** submenu inside this archive. Builds 0/1 and 10/11 are a + `DELTASABER / SYLPHEED A.I.` plate that was **never seen running**, in the boot + path, any title-side screen, or the attract loop. βœ… measured against live + captures for the four English screens the boot path shows; + [`ui-title-build-map.md`](../re/ui-title-build-map.md). + **Withdrawn:** the earlier "builds 6/8/9 are submenus" β€” 8 is the Japanese main + menu. The other four main-menu buttons leave the archive (`GP_SAVE_LOAD`, + `GP_TUTORIAL`, `GP_OPTIONS`, `GP_MISSION_SELECT` are the likely destinations by + name β€” an inference, not a measurement). * **Buttons are identifiable as data.** Element kind `0x3002` = button, `0x0` = decoration, `0x10` = primitive. βœ… decoded. * **Menu order is geometric.** Buttons sorted top-to-bottom by resting Y. This is @@ -73,7 +82,8 @@ authored version can be deleted. * **The logo splash is a screen, not a video.** `logo1`–`logo4` are manifest-bound with no `.wmv` on the disc. βœ… * **Sprites carry their own labels.** No font rendering or localisation is needed - for this milestone. βœ… + for this milestone. βœ… β€” and the localisation is *already baked in*: the + Japanese screens are separate builds in the same pak, not a text swap. ## Facts the port will trip over diff --git a/docs/re/INDEX.md b/docs/re/INDEX.md index f8f2b7c..719c04b 100644 --- a/docs/re/INDEX.md +++ b/docs/re/INDEX.md @@ -149,6 +149,7 @@ files, which is how the same ground got covered twice. | [`title-crash-stl-tree.md`](title-crash-stl-tree.md) | The title-screen crash is an STL `map`/`set` erase on a bad iterator | βœ… CONFIRMED β€” the guest throws std::out_of_range from an STL | | [`ui-paint-order-third-permutation.md`](ui-paint-order-third-permutation.md) | A third measured paint order β€” tool built and validated, screen not reached | βœ… the reader works and is CONFIRMED against both previously | | [`ui-quad-class-foothold.md`](ui-quad-class-foothold.md) | The guest's UI quad class β€” a foothold found from the capture's vertex layout | 🟑 PROBABLE for the identification below (it is a static read, but | +| [`ui-title-build-map.md`](ui-title-build-map.md) | Which `GP_TITLE` build is which screen state | βœ… CONFIRMED for title / `PRESS β’Ά` / main menu / `EXTRAS` against live captures; the archive is 8 screens Γ— EN/JP, and "6/8/9 are submenus" is withdrawn | | [`ui-title-paint-order-capture.md`](ui-title-paint-order-capture.md) | The title screen's paint order, measured from the guest's draw submissions | βœ… CONFIRMED β€” the order in which the running game paints the title | | [`upstream-baseline.md`](upstream-baseline.md) | A stock-upstream baseline runs Stage 02 crash-free | βœ… CONFIRMED β€” upstream canary_experimental + only the pad | | [`weapon-datasheet-runtime.md`](weapon-datasheet-runtime.md) | Weapon DATA SHEET β€” runtime capture (Route B) | 🟑 first dynamic capture, 2026-07-28. The Arsenal's Gallery Mode panel is a | diff --git a/docs/re/METHOD.md b/docs/re/METHOD.md index 7d94f63..b216164 100644 --- a/docs/re/METHOD.md +++ b/docs/re/METHOD.md @@ -117,3 +117,16 @@ agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the * **Measure animation in submitted frames, not in seconds.** `VdSwap` counts are the guest's own frames, so an emulator at 80 % of real time does not move them; a stopwatch reading does, silently and by an unknown factor. +* **This game's menus drop d-pad presses shorter than ~0.3 s.** `pad.py dpad` + defaults to 0.06 s, and its docstring says longer "auto-repeats and + overshoots". On the title main menu that default is *dropped*: four presses at + 0.12 s moved the cursor one step, four at 0.20 s moved it none, while + 0.30/0.50/0.80 s each moved it exactly one step and none of them repeated. A + scripted navigation that comes out one item short is this, not a wrong item + count β€” screenshot after every step and check the cursor rather than trusting + the press count. +* **A screenshot taken right after a transition can catch a screen mid-fade.** + A grab 2.5 s after β’· returned the game to the title showed the title art with + no `PRESS β’Ά BUTTON` plate; one second later the plate was there. That very + nearly went into the corpus as "the returned title has no plate". Sample a + changing screen several times before writing down what it does *not* contain. diff --git a/docs/re/REFUTED.md b/docs/re/REFUTED.md index 943a517..0278c0a 100644 --- a/docs/re/REFUTED.md +++ b/docs/re/REFUTED.md @@ -35,6 +35,12 @@ neighbourhood, not just the line. ## Screens, classes and RTTI +* "`GP_TITLE` builds 6/8/9 are three submenus" β†’ **8 is the JAPANESE main + menu**, and 6/9 are the English and Japanese `EXTRAS` submenu. `GP_TITLE` + holds eight screens shipped twice (EN/JP), and exactly one submenu. See + [`ui-title-build-map.md`](ui-title-build-map.md). +* "the `PRESS β’Ά BUTTON` plate is a state of the title build" β†’ it is **its own + build** (2/3), composited over build 4 and faded in a beat later. * "the RTTI route can name the anonymous classes" β†’ 1 150 vtables: 1 150 `ANON_`, 0 `rtti_present`, 0 base classes. * "the sibling vtable methods name the class" β†’ they cannot. diff --git a/docs/re/captures/title-builds/live-attract-title-press-a-band.png b/docs/re/captures/title-builds/live-attract-title-press-a-band.png new file mode 100644 index 0000000..7966fe2 Binary files /dev/null and b/docs/re/captures/title-builds/live-attract-title-press-a-band.png differ diff --git a/docs/re/captures/title-builds/live-extras.png b/docs/re/captures/title-builds/live-extras.png new file mode 100644 index 0000000..c215b1a Binary files /dev/null and b/docs/re/captures/title-builds/live-extras.png differ diff --git a/docs/re/captures/title-builds/live-main-menu-options-focused.png b/docs/re/captures/title-builds/live-main-menu-options-focused.png new file mode 100644 index 0000000..556db64 Binary files /dev/null and b/docs/re/captures/title-builds/live-main-menu-options-focused.png differ diff --git a/docs/re/captures/title-builds/live-main-menu.png b/docs/re/captures/title-builds/live-main-menu.png new file mode 100644 index 0000000..0086e06 Binary files /dev/null and b/docs/re/captures/title-builds/live-main-menu.png differ diff --git a/docs/re/captures/title-builds/live-title-press-a.png b/docs/re/captures/title-builds/live-title-press-a.png new file mode 100644 index 0000000..c3b563a Binary files /dev/null and b/docs/re/captures/title-builds/live-title-press-a.png differ diff --git a/docs/re/captures/title-builds/title-build-contact-sheet.png b/docs/re/captures/title-builds/title-build-contact-sheet.png new file mode 100644 index 0000000..556db87 Binary files /dev/null and b/docs/re/captures/title-builds/title-build-contact-sheet.png differ diff --git a/docs/re/ui-title-build-map.md b/docs/re/ui-title-build-map.md new file mode 100644 index 0000000..9a6cf1d --- /dev/null +++ b/docs/re/ui-title-build-map.md @@ -0,0 +1,107 @@ +# Which `GP_TITLE` build is which screen β€” measured against the running game + +**Status:** βœ… `CONFIRMED` for the four screens the boot path actually shows +(title art, `PRESS β’Ά BUTTON`, main menu, `EXTRAS`); 🟑 `PROBABLE` for their +Japanese twins; ❔ open for the two `DELTASABER` plates. + +Answers [MISSION Q2](../port/MISSION.md). The previous statement β€” *"build 4 +title, 5 main menu, 6/8/9 submenus"* β€” is **partly wrong** and is withdrawn: +build 8 is the **Japanese main menu**, not a submenu, and `GP_TITLE` holds +exactly **one** submenu (`EXTRAS`), in two languages. + +## The archive is eight screens, each shipped twice + +`GP_TITLE.pak` has 16 entries; `sylpheed-cli screen list` calls 12 of them +composable builds. The 16 fall into **eight pairs**, and each pair's two members +have near-identical sizes and name hashes that differ by a constant β€” one +character of the name apart: + +| entry | hash | bytes | build idx | pair | +|---|---|---|---|---| +| 0 | `01a2db9c` | 483 958 | 0 | A | +| 1 | `0ff0b8a8` | 483 958 | 1 | A | +| 2 | `285d8849` | 267 014 | 2 | B | +| 3 | `369773cb` | 267 014 | 3 | B | +| 4 | `a60fcb85` | 12 278 666 | 4 | C | +| 7 | `b483e6e6` | 13 363 328 | 7 | C | +| 5 | `a715f485` | 6 977 437 | 5 | D | +| 8 | `b58a0fe6` | 6 931 653 | 8 | D | +| 6 | `a81c1d85` | 6 549 126 | 6 | E | +| 9 | `b69038e6` | 6 548 438 | 9 | E | +| 10 | `cdba806e` | 426 473 | β€” | F | +| 13 | `db2ea1f8` | 423 333 | β€” | F | +| 11 | `cec0a96e` | 999 643 | β€” | G | +| 14 | `dc34caf8` | 999 643 | β€” | G | +| 12 | `cf2a8ccd` | 1 774 639 | 10 | H | +| 15 | `dd56d99b` | 1 774 639 | 11 | H | + +For the three pairs whose members differ visibly β€” C, D, E β€” **the difference is +English versus Japanese**: build 7 is the title art with the katakana subtitle +γƒ—γƒ­γ‚Έγ‚§γ‚―γƒˆ シルフィード, build 8 the main menu reading 新規 / ロード / +チγƒ₯γƒΌγƒˆγƒͺをル / γ‚ͺプション / γ‚¨γ‚―γ‚Ήγƒˆγƒ©, build 9 the `EXTRAS` submenu as +γ‚¨γ‚―γ‚Ήγƒˆγƒ©. That is the whole of the language split we can see. In pairs A, B and +H the two members render **byte-identical PNGs** β€” the archive still carries two +copies, but the artwork does not change with the language. + +Pairs F and G are the four entries `screen list` does *not* classify as builds. +They are not identified here. + +## The map + +Contact sheet of every render: +[`captures/title-builds/title-build-contact-sheet.png`](captures/title-builds/title-build-contact-sheet.png). + +| build | what it is | confirmed how | +|---|---|---| +| 0, 1 | a `DELTASABER / SYLPHEED A.I.` plate low-left on black, no background | ❔ **not observed running.** Never seen in the boot path, the main menu, `EXTRAS` or `MISSION SELECT` | +| **2**, 3 | the `PRESS β’Ά BUTTON` plate β€” **an overlay build of its own**, not a state of build 4 | βœ… seen composited over build 4 on the live title, at the same rect our render puts it | +| **4** | title art, English (`PROJECT SYLPHEED`, β„’, `(C)2006,2007 SQUARE ENIX`) | βœ… [`live-title-press-a.png`](captures/title-builds/live-title-press-a.png) | +| 7 | the same, Japanese | 🟑 renders as the JP twin of build 4; the container runs an English locale, so it was not seen | +| **5** | main menu, English: NEW GAME / LOAD GAME / TUTORIAL / OPTIONS / EXTRAS, footer `β’Ά : OK` | βœ… [`live-main-menu.png`](captures/title-builds/live-main-menu.png) β€” element for element | +| 8 | the same, Japanese | 🟑 as above | +| **6** | the `EXTRAS` submenu, English: MISSION SELECT / MOVIE THEATER / BACK, footer `β’Ά : OK β’· : Back` | βœ… [`live-extras.png`](captures/title-builds/live-extras.png) | +| 9 | the same, Japanese | 🟑 as above | +| 10, 11 | the same `DELTASABER` plate as build 0, over a dark circuit-line background | ❔ **not observed running** | + +**Reach of the two negatives.** Builds 0/1 and 10/11 were looked for in: the whole +boot sequence (a 5 s-cadence filmstrip from launch to the title, ~190 s), the +title, the main menu, the `EXTRAS` submenu, the `LOAD GAME` slot list, the +transition into `MISSION SELECT` (a 40-frame burst), and the attract cycle. They +appear in none of them. The obvious remaining candidate is a *long* load β€” a +mission launch β€” which is out of this objective's scope; they are most likely a +loading/AI-chatter plate. That is a hypothesis, not a result. + +## Three things the captures settle beyond the map + +**The live title is two builds composited.** Build 4 draws the art; build 2 draws +`PRESS β’Ά BUTTON` on top, and it **fades in a beat later** β€” a screenshot taken +2.5 s after arriving at the title has the art and no plate, one taken ~1 s later +has both. The port must treat the plate as its own timed element. + +**The attract-loop title carries the plate too.** After ~8–10 s idle the title +fades to black, a full-motion video plays for ~85 s, and the title comes back β€” +*with* `PRESS β’Ά BUTTON` +([`live-attract-title-press-a-band.png`](captures/title-builds/live-attract-title-press-a-band.png)). +This is consistent with, and adds nothing to, the draw-quad comparison in +[`canary-scripted-input-traps.md`](canary-scripted-input-traps.md): the plate is +not the tell that distinguishes the boot title from the attract title. + +**`EXTRAS` is the only main-menu destination inside `GP_TITLE`.** β’Ά on `EXTRAS` +opens build 6 β€” measured. The other four destinations leave the archive: β’Ά on +`LOAD GAME` opened a `LOAD GAME` slot list, and β’Ά on `MISSION SELECT` inside +`EXTRAS` opened a `MISSION SELECT` screen, neither of which is a `GP_TITLE` +build. `dat/` carries `GP_SAVE_LOAD.pak`, `GP_TUTORIAL.pak`, `GP_OPTIONS.pak`, +`GP_MISSION_SELECT.pak` and `GP_MOVIE_THEATER.pak`; **that those are the archives +behind the other four buttons is an inference from the names, not a measurement.** + +## How to reproduce + +```bash +sylpheed-cli screen list "$SYLPHEED_DISC/dat/GP_TITLE.pak" +sylpheed-cli screen render --build 6 "$SYLPHEED_DISC/dat/GP_TITLE.pak" /tmp/b6.png +tools/re-capture/boot_menu.sh q2 # boots to the main menu, cursor on NEW GAME +tools/re-capture/pad.py dpad down 0.35 # x4 -> EXTRAS +tools/re-capture/pad.py tap A 0.30 +``` + +Mind the d-pad hold β€” see [`METHOD.md`](METHOD.md).