This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docs/re/structures/result-screens.md
Sylpheed RE agent 35a35f753f re: the EX_ selection is shown - a mode word at +184 tested against 3
result-screens.md left this explicitly open: "the selection has not been shown".
It is shown now. Both screens that reference EX_ names carry the same
five-instruction idiom immediately before the choice - sub_822814D8 at 0x822815b4
and sub_8227A3A0 at 0x8227a408:

  lwz    r11, 4(rX)              the owning object
  lwz    r11, 184(r11)           a mode word at +184
  addi   r11, r11, -3
  cntlzw r11, r11
  rlwinm r11, r11, 27, 31, 31    r11 = 1 iff [+184] == 3
  cmpli  cr6, 0, r11, 0x0
  bc     12, 4*cr6+eq, <plain>   not 3 -> STAGE_RESULT / OVERVIEW
                                 else  -> EX_STAGE_RESULT / EX_OVERVIEW

cntlzw of zero is 32, and rotating left 27 lifts bit 5 into bit 31, so the
sequence is a branchless equals-3 test. The equal-to-zero branch takes the plain
name, so EX_ is chosen exactly when the word is 3.

A partition over the three key-list loaders the corpus already names:

                        loads +184   does not
  references EX_ names       2           0
  does not                   0           1

sub_822814D8 and sub_8227A3A0 both load it; sub_82286BC8, which references no EX_
name, has no +184 access at all. Both off-diagonal cells are empty.

3 is the game's own EXTRA. challenge-mission-gate already established the
vocabulary for this constant at a three-way switch: == 3 is EXTRA, == 5 or 6 is
CHALLENGE, otherwise FILE. So the prefix reads literally - EX_ is the EXTRA
variant.

That REFINES the doc's tentative reading rather than confirming it. The section
proposed "EX_ = the challenge-mission debriefing" by analogy with _EXn on asset
names; the measured constant is EXTRA, which in the game's own three-way
vocabulary is a DIFFERENT kind from CHALLENGE (5/6).

Boundary of what was measured: the EXTRA = 3 constant is established at +144 of
the stage-loader class, while the word tested here is at +184 of [object + 4].
Same constant and the same EX/EXTRA naming, but two different offsets in what may
be two different objects - that the two fields are the same field is NOT shown,
only that both compare a mode word against 3.

All seventeen artefacts byte-identical.
2026-08-28 10:51:16 +00:00

6.6 KiB

✅ The debriefing and pilot-record screens — STAGE_RESULT, OVERVIEW, EX_OVERVIEW

  • Where: tables.pak (the menu config pak), records STAGE_RESULT, OVERVIEW, EX_OVERVIEW; key lists compiled into the executable at sub_822814D8 and sub_8227A3A0 (found by the base-solver, player-tuning-tables).
  • Related: mission-scoring owns the rules (Score_* in the stage settings); this is the readout. savegame-format documents the same compiled-key-list shape for the LOAD/SAVE screen.

The shape was already known — for other screens

savegame-format establishes it: "the LOAD/SAVE screen's config key list is compiled into the executable, as a pointer array of key strings — the same shape as the Arsenal's (whose keys sit a few hundred bytes earlier and match the pak record exactly)", run starting 0x820A0074. sub_82286BC8's 18-name block is exactly that list — 17 of its 18 are a tables.pak field or record name, so it is the documented save-screen list and nothing new. Its lone residual is PLAYER_AMMO_LESS_10, which is not a tables.pak name at all.

✅ Two more screens, and the key lists match their records exactly

block names all present in tables.pak?
sub_822814D8 24 24 / 24
sub_8227A3A0 21 21 / 21

And the arithmetic closes against the records themselves:

  • sub_822814D8 = the debriefing screen. 24 names = 2 screen ids (STAGE_RESULT, EX_STAGE_RESULT) + 21 stage_* fields + one sound cue (SE_BOSS_CORE_CHARGE). The tables.pak record STAGE_RESULT has exactly 21 fields (2 objects, both 21).
  • sub_8227A3A0 = the pilot record / career screen. 21 names = 5 screen ids (LAST_RESULT, EX_BASE, EX_MAIN, EX_OVERVIEW, OVERVIEW) + 7 ex_overview_* + 9 overview_*. The records EX_OVERVIEW and OVERVIEW have exactly 7 and 9 fields (2 objects each).

2+21+1 = 24 and 5+7+9 = 21, with 21/7/9 measured independently off the pak.

The debriefing readout, in full

stage_num_shoot_down_aircrafts   stage_points_shoot_down_aircrafts
stage_num_shoot_down_ships       stage_points_shoot_down_ships
                                 stage_points_shoot_down_others
stage_weight_shoot_down
stage_num_main_objectives        stage_points_main_objectives
stage_num_sub_objectives         stage_points_sub_objectives
stage_clear_time                 stage_points_clear_time
stage_shoot_down_ratio           stage_points_shoot_down_ratio
stage_damages_friendly_ships     stage_points_damages_friendly_ships
stage_damages_wingman            stage_points_damages_wingman
                                 stage_points_friendly_fire
stage_total_points               stage_rank

🔑 Nine num/points pairs plus three points-only lines — the screen shows a raw count and its score contribution for kills by class, objectives, time, ratio and both damage categories; friendly_fire, shoot_down_others and weight have no counter column. That is the same partition mission-scoring measures on the settings side.

The career readout

overview_points, _total_play_time, _clear_stages, _retry_times, _shoot_down_aircrafts, _shoot_down_ships, _shoot_down_weight — seven, and OVERVIEW adds overview_rank and overview_medals. The EX_ twin has the seven and neither of the two, which is what makes EX_ the reduced variant rather than a different screen.

🟡 Not settled: what EX_ means (a second profile? the online/leaderboard variant?) — but see stage-numbering-and-player-craft: _EXn on an asset name is measured to mean "the n-th challenge mission", which makes "EX_ = the challenge-mission debriefing" a consistent reading of why this twin drops overview_rank and overview_medals. Not adopted — the selection has not been shown — EX_BASE, EX_MAIN, EX_STAGE_RESULT and EX_FONT are keys with no record of that name, so the prefix is a screen-id convention, not a table. And PLAYER_AMMO_LESS_10 is unexplained.

Reproduce: parse tables.pak with tools/re-capture/unitgroup.py and count the fields of the three records; take the key lists from the sub_822814D8 / sub_8227A3A0 / sub_82286BC8 sections of ../data/name-block-bases.txt.

✅ The EX_ selection, shown at last — a mode word tested against 3

The section above left this open: "the selection has not been shown". It is shown now. Both screens that reference EX_ names carry the same five-instruction idiom immediately before the choice — sub_822814D8 at 0x822815b4 and sub_8227A3A0 at 0x8227a408:

lwz    r11, 4(rX)          ; the owning object
lwz    r11, 184(r11)       ; a mode word at +184
addi   r11, r11, -3
cntlzw r11, r11
rlwinm r11, r11, 27, 31, 31 ; r11 = 1  iff  [+184] == 3
cmpli  cr6, 0, r11, 0x0
bc     12, 4*cr6+eq, <plain>  ; not 3  -> STAGE_RESULT / OVERVIEW
                              ; else   -> EX_STAGE_RESULT / EX_OVERVIEW

cntlzw of zero is 32; rotating left 27 lifts bit 5 into bit 31, so the sequence is a branchless "equals 3" test. The equal-to-zero branch takes the plain name, so EX_ is chosen exactly when the word is 3.

A small partition over the three key-list loaders the corpus already names:

loads +184 does not
references EX_ names 2 0
does not 0 1

sub_822814D8 and sub_8227A3A0 both load it; sub_82286BC8, which references no EX_ name, has no +184 access at all. Both off-diagonal cells are empty.

🔑 3 is the game's own EXTRA — and that is not CHALLENGE

challenge-mission-gate already established the vocabulary for this constant at a three-way switch: == 3 → EXTRA, == 5 or 6 → CHALLENGE, otherwise FILE. So the prefix reads literally: EX_ is the EXTRA variant.

⚠️ This refines the tentative reading above rather than confirming it. That section proposed "EX_ = the challenge-mission debriefing" by analogy with _EXn on asset names. The measured constant is EXTRA, which in the game's own three-way vocabulary is a different kind from CHALLENGE (5/6). EX_ tracks EXTRA specifically.

⚠️ The boundary of what was measured: the EXTRA = 3 constant is established at +144 of the stage-loader class, while the word tested here is at +184 of [object + 4]. Same constant, same EX/EXTRA naming, two different offsets in what may be two different objects — that the two fields are the same field is not shown, only that both compare a mode word against 3.