re: r0 is not a base register - the last shortlisted row withdrawn
sub_825F2CF0 / sub_825F2F88 (r0, 30 names each, 97% disc names) are not name-block readers at all: they are the compiler's VMX save/restore helper pair. 145 instructions each, 72 differ, every difference stvx<->lvx over v14..v127. Root cause: in `addi rD, rA, N` the rA slot reads as literal zero when it names r0, so `addi r11, r0, -N` is `li r11, -N` - vector spill offsets, not displacements. The solver excluded r1 only; the bogus base landed inside the stage-settings name block, dense enough to "resolve" 30 real field names. name_block_bases.py now skips r0 as well. Rows 277 -> 261, functions 190 -> 176, non-64K bases 170 -> 154, data-table rows 53 -> 50; 154+107=261 and 277-16=261. Artefact diff -100/+3, every removed row line carries r0, control sub_82341A20 r30 = 0x82088F94 217/226 untouched. Nothing lost: all 30 names are a strict subset of sub_8230D1F8 r29 (129 names), the stage-settings loader already in the corpus. String-xref join agrees - FinalPassBG, FogMinDistance, ScreenColorR, ExposureKey_BeginValue each exist once with exactly one xref, from sub_8230D1F8. Fourteen other artefacts byte-identical; name-block-bases.txt byte-identical on a second run.
This commit is contained in:
@@ -5497,3 +5497,59 @@ field**; counting "24 `Detail_*` things" would merge two unrelated tables.
|
||||
`Extra01…04` map onto the four challenge missions the corpus knows. And the last
|
||||
shortlisted row (`sub_825F2CF0`/`sub_825F2F88` post-processing, two functions on
|
||||
one base) is still unopened.
|
||||
|
||||
---
|
||||
|
||||
## 🔴✅ 2026-08-28 — the last shortlisted row is an artefact: `r0` is not a base register
|
||||
|
||||
Item (a), the final unopened row: `sub_825F2CF0` + `sub_825F2F88`, **`r0`**, 30
|
||||
names each on the same base `0x8209EB30`, 97 % disc names. The framing was "a
|
||||
pair, or a clone?" — **both wrong. Neither function reads a name block.**
|
||||
|
||||
🔑 **Diffing the two settles it in one look.** 145 instructions each, **72
|
||||
differ, and every difference is the same substitution**: `stvx`/`stvx128` on one
|
||||
side, `lvx`/`lvx128` on the other, over v14…v127. They are the compiler's **VMX
|
||||
register save / restore helper pair**. A pair, then — but the pairing is
|
||||
spill/reload, not two readers of one table.
|
||||
|
||||
🔴 **The root cause is a whole class of false positive.** In PowerPC
|
||||
`addi rD, rA, N`, the `rA` slot **reads as literal zero when it names r0** — the
|
||||
form is `li rD, N`. The 72 `addi r11, r0, -N` are vector spill offsets, plain
|
||||
immediates. The solver excluded `r1` (stack pointer) and nothing else, so it took
|
||||
them as displacements, voted a base, and landed `0x8209EB30` — *inside the
|
||||
stage-settings name block*, where a scatter of 16-byte-spaced negative offsets is
|
||||
dense enough to "resolve" 30 real field names.
|
||||
|
||||
⚠️ **A 97 %-disc-names row can still be an artefact.** The disc-name test measures
|
||||
what the *base region* contains, not that the function reads it. That is a
|
||||
correction to the 53-of-277 classification's own premise.
|
||||
|
||||
✅ **Nothing is lost, and the real reader was already ours.** All 30 withdrawn
|
||||
names are a **strict subset** of `sub_8230D1F8 r29` (base `0x8209FD28`, 129
|
||||
names) — the stage-settings loader. The string-xref join agrees independently:
|
||||
`FinalPassBG`, `FogMinDistance`, `ScreenColorR` and `ExposureKey_BeginValue` each
|
||||
exist **once** in the image with **exactly one** xref, from `sub_8230D1F8`.
|
||||
`NoseCameraFOV` and `GlareType` exist **twice**, the second copy read by
|
||||
`sub_822AE628` — the hangar's game-wide defaults, the double-string-block trap
|
||||
the corpus already records.
|
||||
|
||||
**Fix:** `name_block_bases.py` now skips `reg in ('r0', 'r1')`. Every number moves
|
||||
by exactly the 16 `r0` rows: rows **277 → 261**, distinct functions **190 → 176**
|
||||
(14, not 16 — two of those functions keep a row through another register),
|
||||
non-64K bases **170 → 154**, 64K bases 107 unchanged, data-table schemas
|
||||
**53 → 50**. Both ways: `154 + 107 = 261` and `277 − 16 = 261`. The artefact diff
|
||||
removes 100 lines and adds 3; **every removed row line carries `r0`**, the three
|
||||
added lines are those counts, and the control is untouched (`sub_82341A20 r30 =
|
||||
0x82088F94`, 217/226). The three withdrawn data-table rows are `sub_825F2CF0`,
|
||||
`sub_825F2F88` and `sub_82222E70` (15 names, 100 % disc, same region, same
|
||||
mechanism); the "six camera/fog readers" are really **three** (`sub_8247DFC0`,
|
||||
`sub_823B2620`, `sub_822C7480`, all `r31`, all based in `0x8209E6xx`).
|
||||
|
||||
Written up in `docs/re/structures/player-tuning-tables.md`; `INDEX.md` updated.
|
||||
|
||||
🟡 Not settled: the 🟡 stalled `SpaceSize`/`GlareType`/`Nebura_*` numerics are no
|
||||
closer — their reader was already known to be `sub_8230D1F8`, and this row never
|
||||
was a second one. **The shortlist is now empty.** Still open: whether a `stvx`-
|
||||
style helper elsewhere fooled a *non*-`r0` row (the 64K-boundary cluster is the
|
||||
remaining known false-positive mode, unaddressed); `Detail_Window_Known/_Unknown`;
|
||||
whether `Extra01…04` map onto the challenge missions.
|
||||
|
||||
@@ -106,7 +106,7 @@ files, which is how the same ground got covered twice.
|
||||
| [`structures/stage16-boss.md`](structures/stage16-boss.md) | The Stage 16 boss end to end — object, loader `sub_82315AE8`, collision | ✅ CONFIRMED — 19/19 of the loader's names are `Guardian`/`Core` fields; 5 disc fields have no string in the image (two same-length controls do) |
|
||||
| [`structures/leaderboard-screen.md`](structures/leaderboard-screen.md) | The leaderboard screen — `sub_8219E560`, 12 panel elements, 4 board scopes, 6 modes | ✅ CONFIRMED — 18 names = 13 records + 5 fields; all 12 `Detail_*` records named, zero residual; ⚠️ 12 `Detail*` records and 12 `Detail*` fields are DISJOINT |
|
||||
| [`structures/result-screens.md`](structures/result-screens.md) | The debriefing and pilot-record screens — `STAGE_RESULT` 21 fields, `OVERVIEW` 9, `EX_OVERVIEW` 7 | ✅ CONFIRMED — the compiled key lists `sub_822814D8` (24/24) and `sub_8227A3A0` (21/21) match the `tables.pak` records exactly; `2+21+1=24`, `5+7+9=21` |
|
||||
| [`structures/player-tuning-tables.md`](structures/player-tuning-tables.md) | **`PlayerParams`** — the player parameter table: `Booster` flight model, special attacks, 8 analog curves, the S16 boss | ✅✅ `sub_822F9498` is `PlayerParams`'s loader, not the unit loader; **the analog block's reader SOLVED — `sub_821A6CF0`, base `0x820A1630`**, via the new base-solver (277 name-block loaders image-wide, control 217/226 on `sub_82341A20`); 🟡 nothing selects `Booster` |
|
||||
| [`structures/player-tuning-tables.md`](structures/player-tuning-tables.md) | **`PlayerParams`** — the player parameter table: `Booster` flight model, special attacks, 8 analog curves, the S16 boss | ✅✅ `sub_822F9498` is `PlayerParams`'s loader, not the unit loader; **the analog block's reader SOLVED — `sub_821A6CF0`, base `0x820A1630`**, via the new base-solver (261 name-block loaders image-wide after the `r0` correction, control 217/226 on `sub_82341A20`); 🟡 nothing selects `Booster` |
|
||||
| [`structures/hud-config.md`](structures/hud-config.md) | The in-game HUD configuration — 16 records, 419 asset paths, and a per-stage `ResourceTable` | ✅ CONFIRMED — 0 of 419 config paths resolve as pak entries |
|
||||
| [`structures/mission-script-manifest.md`](structures/mission-script-manifest.md) | `Stage\script.tbl`'s 11 non-`MISSION` fields, and the mission dialogue table they name | ✅ CONFIRMED — 1 of 7 values resolves (`message\MissionDialogMessage.tbl`, 200 records), controls in the same sweep |
|
||||
| [`structures/stage-numbering-and-player-craft.md`](structures/stage-numbering-and-player-craft.md) | The disc's stage numbering (S01–S16, S18–S29) and the player's craft per stage | ✅✅ CONFIRMED — two independent files close on 6 + 15 + 1 + 6 = 28 |
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
strings in the image: 7140 addi instructions: 282736
|
||||
|
||||
## 277 functions read a name block through a base register
|
||||
## 261 functions read a name block through a base register
|
||||
function reg base resolved / displacements
|
||||
sub_82341A20 r30 0x82088F94 217 / 226
|
||||
sub_822215D0 r11 0x820A0000 205 / 206
|
||||
@@ -81,14 +81,11 @@
|
||||
sub_8284B398 r11 0x820B0000 40 / 42
|
||||
sub_822F9498 r31 0x82026F24 39 / 83
|
||||
sub_826FBC38 r11 0x82050000 38 / 60
|
||||
sub_826AE390 r0 0x82026F74 37 / 306
|
||||
sub_82338EE0 r31 0x82026F18 36 / 78
|
||||
sub_823AE908 r31 0x82026F24 33 / 71
|
||||
sub_823BDAA8 r11 0x820B0000 33 / 35
|
||||
sub_826AB050 r11 0x82040000 31 / 33
|
||||
sub_82561C70 r11 0x820A90D8 30 / 93
|
||||
sub_825F2CF0 r0 0x8209EB30 30 / 64
|
||||
sub_825F2F88 r0 0x8209EB30 30 / 64
|
||||
sub_822E3EC8 r11 0x820B0000 29 / 32
|
||||
sub_82627B70 r11 0x82030000 29 / 29
|
||||
sub_82297550 r11 0x820B0000 27 / 41
|
||||
@@ -174,8 +171,6 @@
|
||||
sub_8257E270 r5 0x820AE7AC 21 / 31
|
||||
sub_8257E6C0 r5 0x820AE7AC 21 / 31
|
||||
sub_82658790 r11 0x82030000 21 / 26
|
||||
sub_82780C10 r0 0x820A9EAD 21 / 51
|
||||
sub_827D9DD0 r0 0x82074503 21 / 149
|
||||
sub_821A8578 r11 0x82023F00 20 / 25
|
||||
sub_8233C368 r28 0x8208583C 20 / 21
|
||||
sub_8236B608 r11 0x820B0000 20 / 20
|
||||
@@ -190,7 +185,6 @@
|
||||
sub_8232BAA0 r31 0x82034220 17 / 25
|
||||
sub_823B63E0 r31 0x820AE72C 17 / 30
|
||||
sub_82440878 r31 0x82026FF0 17 / 33
|
||||
sub_824B4908 r0 0x82073D58 17 / 122
|
||||
sub_8265A260 r11 0x82030000 17 / 18
|
||||
sub_827A5058 r11 0x82050000 17 / 18
|
||||
sub_8219BB30 r11 0x820244AC 16 / 26
|
||||
@@ -201,10 +195,8 @@
|
||||
sub_82324178 r31 0x82026F14 16 / 28
|
||||
sub_82473448 r31 0x8202EBFC 16 / 29
|
||||
sub_82562BB8 r3 0x820A918C 16 / 20
|
||||
sub_825C2980 r0 0x82052A40 16 / 22
|
||||
sub_826A0040 r11 0x820A01AC 16 / 32
|
||||
sub_82804AD0 r11 0x820A792C 16 / 43
|
||||
sub_82222E70 r0 0x8209E6D8 15 / 27
|
||||
sub_8227F8E0 r31 0x820A0E9C 15 / 20
|
||||
sub_82282DB0 r31 0x820A0E8C 15 / 20
|
||||
sub_822E3EC8 r10 0x820B0000 15 / 15
|
||||
@@ -216,9 +208,7 @@
|
||||
sub_823C0C58 r31 0x82034270 15 / 18
|
||||
sub_82565C80 r11 0x820A5574 15 / 42
|
||||
sub_825DA790 r26 0x820A3B4C 15 / 20
|
||||
sub_8265DFB8 r0 0x82074ECA 15 / 98
|
||||
sub_82664700 r11 0x82030000 15 / 16
|
||||
sub_82787E38 r0 0x82074B66 15 / 76
|
||||
sub_8285F2C8 r5 0x820AE7AC 15 / 15
|
||||
sub_82860290 r3 0x820AE7AC 15 / 15
|
||||
sub_82860670 r3 0x820AE7AC 15 / 15
|
||||
@@ -226,7 +216,6 @@
|
||||
sub_8220ED30 r31 0x820A0E9C 14 / 21
|
||||
sub_8221F700 r11 0x820A0000 14 / 18
|
||||
sub_82288E70 r11 0x820B0000 14 / 23
|
||||
sub_822CC130 r0 0x82026F74 14 / 31
|
||||
sub_822F2E58 r31 0x820A97E4 14 / 27
|
||||
sub_82308AB8 r31 0x82034200 14 / 27
|
||||
sub_8230BB58 r11 0x820B0000 14 / 15
|
||||
@@ -241,7 +230,6 @@
|
||||
sub_823B2620 r31 0x8209E710 14 / 24
|
||||
sub_823D3BE0 r31 0x820B47D4 14 / 24
|
||||
sub_82529708 r25 0x820AAA6C 14 / 20
|
||||
sub_8252C4E8 r0 0x82074617 14 / 70
|
||||
sub_825635C8 r31 0x8209E230 14 / 22
|
||||
sub_8261F2C0 r11 0x8208AB54 14 / 21
|
||||
sub_82659DF0 r11 0x82030000 14 / 14
|
||||
@@ -254,8 +242,6 @@
|
||||
sub_823800A8 r31 0x82001C4C 13 / 21
|
||||
sub_823A3C30 r31 0x82034270 13 / 18
|
||||
sub_823BF6D8 r31 0x82034270 13 / 17
|
||||
sub_82435448 r0 0x82027040 13 / 52
|
||||
sub_824B42E8 r0 0x820743A3 13 / 66
|
||||
sub_824E76D0 r10 0x8209FC64 13 / 22
|
||||
sub_8257DD20 r4 0x820342D0 13 / 15
|
||||
sub_8257DD20 r5 0x820342D0 13 / 15
|
||||
@@ -266,7 +252,6 @@
|
||||
sub_82621400 r11 0x82030000 13 / 14
|
||||
sub_82622448 r11 0x8202B13C 13 / 18
|
||||
sub_8263D478 r11 0x82030000 13 / 16
|
||||
sub_826A7BF0 r0 0x82074DCE 13 / 85
|
||||
sub_827030F8 r11 0x82050000 13 / 13
|
||||
sub_827B0098 r11 0x82050000 13 / 15
|
||||
sub_82193648 r11 0x820A8278 12 / 22
|
||||
@@ -280,12 +265,11 @@
|
||||
sub_82625890 r11 0x82030000 12 / 14
|
||||
sub_826ACC98 r11 0x82040000 12 / 18
|
||||
sub_826FA758 r11 0x820A81F0 12 / 26
|
||||
sub_82766DB0 r0 0x8207454A 12 / 71
|
||||
sub_82766DB0 r11 0x82050000 12 / 29
|
||||
sub_827D7C00 r11 0x82060000 12 / 14
|
||||
|
||||
## Confidence split
|
||||
bases with a non-zero low half (a real `addis`+`addi` pair): 170
|
||||
bases with a non-zero low half (a real `addis`+`addi` pair): 154
|
||||
bases on a 64K boundary (LOW CONFIDENCE, see below) : 107
|
||||
0x820B0000 x82 rows
|
||||
0x82030000 x10 rows
|
||||
@@ -297,7 +281,7 @@
|
||||
|
||||
## Is the row a DATA-TABLE schema? (names that are IDXD record/field names on the disc)
|
||||
distinct IDXD record+field names disc-wide: 13450
|
||||
rows that are >=50% disc names and >=8 names: 53 / 277
|
||||
rows that are >=50% disc names and >=8 names: 50 / 261
|
||||
sub_82341A20 r30 0x82088F94 217 names 89% disc
|
||||
sub_822215D0 r11 0x820A0000 205 names 98% disc
|
||||
sub_8230D1F8 r29 0x8209FD28 129 names 97% disc
|
||||
@@ -306,8 +290,6 @@
|
||||
sub_822AE628 r11 0x820B0000 81 names 67% disc
|
||||
sub_823BDAA8 r11 0x820B0000 33 names 88% disc
|
||||
sub_82561C70 r11 0x820A90D8 30 names 50% disc
|
||||
sub_825F2CF0 r0 0x8209EB30 30 names 97% disc
|
||||
sub_825F2F88 r0 0x8209EB30 30 names 97% disc
|
||||
sub_82297550 r11 0x820B0000 27 names 67% disc
|
||||
sub_822A2F00 r11 0x820B0000 27 names 70% disc
|
||||
sub_823BDAA8 r10 0x820B0000 25 names 100% disc
|
||||
@@ -328,7 +310,6 @@
|
||||
sub_82286BC8 r11 0x820B0000 18 names 100% disc
|
||||
sub_821AA1B0 r31 0x820A97CC 16 names 94% disc
|
||||
sub_82804AD0 r11 0x820A792C 16 names 88% disc
|
||||
sub_82222E70 r0 0x8209E6D8 15 names 100% disc
|
||||
sub_8227F8E0 r31 0x820A0E9C 15 names 100% disc
|
||||
sub_82282DB0 r31 0x820A0E8C 15 names 100% disc
|
||||
sub_823479B8 r28 0x820864F4 15 names 100% disc
|
||||
@@ -1118,12 +1099,6 @@
|
||||
assembler.prd_stack->Size() == 1 , ExpAdjust=%d MiniFetch=FALSE, PrefetchCount=%d
|
||||
MiniFetch=TRUE
|
||||
|
||||
sub_826AE390 (r0, base 0x82026F74) names 37:
|
||||
vs_3_sw vs_3_0 vs_2_x vs_2_sw vs_2_a vs_1_1 vs_1_0 vs.3.xps vs.3.swx vs.3.sw
|
||||
vs.3.0 vs.2.x vs.2.sw vs.2.a vs.1.1 vs.1.0 tx_1_0 ps_3_sw ps_3_0 ps_2_x ps_2_sw
|
||||
ps_2_b ps_2_alpha2 ps_2_a ps_1_4 ps_1_3 ps_1_2 ps_1_1 ps_1_0 ps.3.sw ps.3.0
|
||||
ps.2.x ps.2.sw ps.2.b ps.2.a ps.1.4 ps.1.3
|
||||
|
||||
sub_82338EE0 (r31, base 0x82026F18) names 36:
|
||||
ps.1.3 vs_3_swx vs_3_0 ps_3_sw vs_2_x vs_2_sw ps_3_0 vs_2_a ps.2.b vs_1_1 ps_2_x
|
||||
vs_1_0 vs.3.xps ps_2_sw ps_2_b vs.3.sw vs.3.0 ps_2_alpha2 vs.2.x vs.2.sw vs.2.a
|
||||
@@ -1252,22 +1227,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
C_PAD_DECODER \x8F\x89\x8A\xFA\x89\xBB
|
||||
Pattern
|
||||
|
||||
sub_825F2CF0 (r0, base 0x8209EB30) names 30:
|
||||
FinalPassBG FinalPassToneRatio FogMinDistance FogMaxDistance FogMinAmount FogMaxAmount
|
||||
FirstAdaptedLuminance ExposureKey_BeginValue NoseCameraFOV NoseCameraPosX
|
||||
NoseCameraPosY NoseCameraPosZ NearCameraFOV NearCameraPosX NearCameraPosY
|
||||
NearCameraPosZ FarCameraFOV FarCameraPosX FarCameraPosY FarCameraPosZ SplinterCell
|
||||
BGRotateScale_%1d GlareType Contrast ColorLayerA ScreenColorR ScreenColorG
|
||||
ScreenColorB FinalPassType FinalPassDR
|
||||
|
||||
sub_825F2F88 (r0, base 0x8209EB30) names 30:
|
||||
FinalPassBG FinalPassToneRatio FogMinDistance FogMaxDistance FogMinAmount FogMaxAmount
|
||||
FirstAdaptedLuminance ExposureKey_BeginValue NoseCameraFOV NoseCameraPosX
|
||||
NoseCameraPosY NoseCameraPosZ NearCameraFOV NearCameraPosX NearCameraPosY
|
||||
NearCameraPosZ FarCameraFOV FarCameraPosX FarCameraPosY FarCameraPosZ SplinterCell
|
||||
BGRotateScale_%1d GlareType Contrast ColorLayerA ScreenColorR ScreenColorG
|
||||
ScreenColorB FinalPassType FinalPassDR
|
||||
|
||||
sub_822E3EC8 (r11, base 0x820B0000) names 29:
|
||||
g_mWorldViewProjection g_mWorldViewProjectionLast g_mObjectToView g_mObjectToViewLast
|
||||
g_mWorld g_Params g_UVParams g_LayerParams g_MapEnable g_MapLayerEnable ColorMap
|
||||
@@ -2145,16 +2104,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
Constant is both a struct member and an array element. defconst: %s
|
||||
Register type not found. Multi-dimensional arrays are not supported. Bad variable name.
|
||||
|
||||
sub_82780C10 (r0, base 0x820A9EAD) names 21:
|
||||
757,228 rou_e009 rou_e008 rou_e006 rou_e005 rou_e003 rou_e004 rou_f202 rou_f201
|
||||
rou_f105 rou_f101 rou_f003 rou_f001 rou_e201 ConditionToDevelop rou_e108 rou_e106
|
||||
rou_e105 rou_e015 rou_e010 rou_e007
|
||||
|
||||
sub_827D9DD0 (r0, base 0x82074503) names 21:
|
||||
hyphensuperior Gravesmall Asmall Msmall colonmonetary notequal sixinferior
|
||||
Dotaccentsmall Ringsmall seveneighths onethird centinferior Aacutesmall 001.002
|
||||
Semibold greaterequal Acircumflex Uacute Ugrave eacute edieresis
|
||||
|
||||
sub_821A8578 (r11, base 0x82023F00) names 20:
|
||||
texdp3 vs_3_sw vs_3_0 vs_2_x vs_2_sw vs_2_a vs_1_1 vs_1_0 vs.3.xps vs.3.sw vs.3.0
|
||||
vs.2.x vs.2.sw vs.2.a vs.1.1 vs.1.0 ps_3_sw ps_3_0 ps_2_x ps_2_sw
|
||||
@@ -2274,10 +2223,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
ps_2_a ps.2.x ps_1_4 ps_1_2 ps.1.0 ps.1.2 ps_1_1 ps.2.b ps_1_0 ps.1.3 ps.3.sw
|
||||
ps.2.a ps.3.0 ps.1.1 ps_1_3 ps.1.4 ps.2.sw
|
||||
|
||||
sub_824B4908 (r0, base 0x82073D58) names 17:
|
||||
Ntilde Lslash acircumflex onesuperior logicalnot fouroldstyle Uacute adieresis
|
||||
atilde ccedilla eacute Ugrave Ydieresis Zcaron notequal product bracketleft
|
||||
|
||||
sub_8265A260 (r11, base 0x82030000) names 17:
|
||||
More than one buffer type specified.
|
||||
Buffer type "%s" does not use a size value.
|
||||
@@ -2347,11 +2292,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
mob_n040 rou_e202 rob_e001 mob_n500 mob_n043 mob_n042 mob_n041 rob_f001 rou_f104
|
||||
rou_f102 rou_e107 1092,457 FlightTime 1066,491 ClearTimes rob_f002
|
||||
|
||||
sub_825C2980 (r0, base 0x82052A40) names 16:
|
||||
FOGEND BORDERCOLORA FOGCOLORA BORDERCOLORG BORDERCOLORB YUVCONSTANTSC33
|
||||
YUVCONSTANTSC31 YUVCONSTANTSC22 YUVCONSTANTSC23 YUVCONSTANTSC32 YUVCONSTANTSC03
|
||||
YUVCONSTANTSC13 YUVCONSTANTSC21 YUVCONSTANTSC11 YUVCONSTANTSC12 FOGCOLORG
|
||||
|
||||
sub_826A0040 (r11, base 0x820A01AC) names 16:
|
||||
PGHUD_RANGE_BAR STAGE_ID_7 PGHUD_RANGE_BAR_EM AsteroidDefinition STAGE_ID_8 STAGE_ID_9
|
||||
STAGE_ID_10 STAGE_ID_11 StageResource STAGE_ID_12 STAGE_ID_13 STAGE_ID_14 STAGE_ID_15
|
||||
@@ -2362,11 +2302,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
PGMANUVA_NUM3EFF PGHUD_ARMS_NUM%d EnumerateUnit SilhouetteModel PGMANUVA_NUM3
|
||||
PGHUD_TYPE_CN WEAPONS SE_main_arm1_attach 903,343 PGTARGET_SP_READY_DLH
|
||||
|
||||
sub_82222E70 (r0, base 0x8209E6D8) names 15:
|
||||
Generic NearCameraPosY Nebura_Size GravityFactor FarCameraPosX FarCameraFOV
|
||||
YawAdjustment EnumerateAIParams RollAdjustment Player NoseCameraFOV FogMinAmount
|
||||
FinalPassToneRatio NearCameraPosZ FarCameraPosZ
|
||||
|
||||
sub_8227F8E0 (r31, base 0x820A0E9C) names 15:
|
||||
ForceBootPlayerCharacterID_11 ForceBootPlayerCharacterID_15 ForceBootPlayerCharacterID_12
|
||||
ForceBootPlayerCharacterID_14 ForceBootPlayerCharacterID_13 ForceBootPlayerCharacterID_3
|
||||
@@ -2429,10 +2364,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
Camera TYPE_END_EVENT A/START MISSION11 MISSION12 MISSION7 MISSION8 MISSION9
|
||||
MISSION10 MISSION15 MISSION16 MISSION17 MISSION18 MISSION13 MISSION14
|
||||
|
||||
sub_8265DFB8 (r0, base 0x82074ECA) names 15:
|
||||
Asmall Bsmall Csmall Dsmall Esmall Fsmall Gsmall Hsmall Ismall Jsmall Ksmall
|
||||
Lsmall Msmall Nsmall Osmall
|
||||
|
||||
sub_82664700 (r11, base 0x82030000) names 15:
|
||||
p->xUR1 = __vspltisw(1);
|
||||
%s = __vmsum3fp(%s, %s);
|
||||
@@ -2448,10 +2379,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
%s = __vsel(%s, %s, %s);
|
||||
|
||||
|
||||
sub_82787E38 (r0, base 0x82074B66) names 15:
|
||||
Ucircumflex bsuperior Zcaron osuperior ssuperior atilde nineoldstyle icircumflex
|
||||
Yacute Udieresis edieresis Psmall zerosuperior aacute dsuperior
|
||||
|
||||
sub_8285F2C8 (r5, base 0x820AE7AC) names 15:
|
||||
%4d / %4d
|
||||
%4d / %4d
|
||||
@@ -2558,10 +2485,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
199,333 360,333 BrokenData 260,367 441,367 AUTO_SAVED CLEARED 260,333 441,333
|
||||
%03d:%02d:%02d 513,367 FlightTime 703,367 RatioOfClear
|
||||
|
||||
sub_822CC130 (r0, base 0x82026F74) names 14:
|
||||
vs_3_sw vs.3.sw vs_1_0 ps_2_alpha2 vs.1.0 vs.2.a vs_2_x vs_1_1 vs.3.xps ps.1.1
|
||||
vs_2_sw vs_3_0 vs.2.x ps.1.3
|
||||
|
||||
sub_822F2E58 (r31, base 0x820A97E4) names 14:
|
||||
STAGE14 STATE_GAME_CLEAR STAGE04 STAGE06 MISSION_SELECT LOAD_BASES STATE_STAND_BY
|
||||
STAGE13 STAGE11 STAGE07 STAGE10 STAGE09 STAGE12 STAGE08
|
||||
@@ -2692,10 +2615,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
LuminanceFX_BrightB LuminanceFX_TonedRatio LuminanceFX_Vignetting
|
||||
LuminanceFX_VignetSharpness
|
||||
|
||||
sub_8252C4E8 (r0, base 0x82074617) names 14:
|
||||
scedilla cacute parenright semicolon quoteright .notdef percent parenleft hyphen
|
||||
Scedilla dcroat Ccaron asciicircum exclam
|
||||
|
||||
sub_825635C8 (r31, base 0x8209E230) names 14:
|
||||
DOF_FarFocal FogLinear FogMinDistance Nebura_Size Nebura_MiddleNear FogMaxAmount
|
||||
Nebura_SpeedScale UnsharpMask_R Nebura_NearAmount FinalPassDB FinalPassBR FinalPassBG
|
||||
@@ -2773,14 +2692,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
__vspltw(%s, 0) __vspltw(%s, 1) __vsel(%s, %s, %s) __vcfux(%s, %d) __vspltisw(0)
|
||||
__vspltw(%s, 2) p->xSR2 __lvx(%s, 0)
|
||||
|
||||
sub_82435448 (r0, base 0x82027040) names 13:
|
||||
ps_1_1 ps_1_4 ps_2_a ps_1_3 ps_1_2 ps.2.x ps_1_0 ps.3.sw ps.3.0 ps.2.sw ps.2.b
|
||||
ps.1.4 ps.2.a
|
||||
|
||||
sub_824B42E8 (r0, base 0x820743A3) names 13:
|
||||
Dieresissmall figuredash dollarinferior Medium Adieresissmall Atildesmall Aringsmall
|
||||
Agravesmall Aacutesmall Ethsmall threequartersemdash agrave partialdiff
|
||||
|
||||
sub_824E76D0 (r10, base 0x8209FC64) names 13:
|
||||
AccPitchFactor AV_AxisMode_Min DecPitchFactor AV_AxisMode_Max GaugeMaximum
|
||||
ChargeMinimum ChargeMaximum AttackTime_Minimum StageResource BackGroundID
|
||||
@@ -2842,10 +2753,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
Internal error 0x%08X while generating code. Please send this shader to xboxds@xbox.com.
|
||||
Microcode comparison failed. Please send your HLSL code to xboxds@xbox.com.
|
||||
|
||||
sub_826A7BF0 (r0, base 0x82074DCE) names 13:
|
||||
periodsuperior Ksmall Jsmall Lsmall Bsmall Csmall Dsmall Esmall Fsmall Gsmall
|
||||
Hsmall Ismall Msmall
|
||||
|
||||
sub_827030F8 (r11, base 0x82050000) names 13:
|
||||
Assertion failed: %s (%s:%u)
|
||||
d:\xenon\jun06\core\private\xtl\graphics\xgraphics\ucode\ssm\statecompiler\ssmstatecompiler.cpp
|
||||
@@ -2925,10 +2832,6 @@ float4 FontPixelShader( VS_OUT In ) : COLOR0
|
||||
LANGUAGE PGMARKTGT PGMARKLOCKON PGMANUVA_EFF3 PGMARK_GAUGE_SUB_BASE FrameAnimationType
|
||||
SYSTEM PGMARK_SHIELD_SUB_BASE PGMARK_GAUGE_BAR PGMARK4 PGMARK3 PGMARK2
|
||||
|
||||
sub_82766DB0 (r0, base 0x8207454A) names 12:
|
||||
notequal lessequal product \x82\x42[`.null Scedilla cacute scedilla B[`.null Cacute
|
||||
Oslashsmall Uacutesmall Udieresissmall
|
||||
|
||||
sub_82766DB0 (r11, base 0x82050000) names 12:
|
||||
instruction options arrays are not supported in inline microcode predication
|
||||
alloc option setGradient instructions muls_prev2 instruction kill instructions
|
||||
|
||||
@@ -151,7 +151,8 @@ against the right answer's 217/226.
|
||||
✅ **Control, with no prior knowledge: the tool recovers `r30 = 0x82088F94` for
|
||||
the unit loader `sub_82341A20`, resolving 217 of 226 displacements.** It also
|
||||
independently recovers `sub_8230D1F8` (129/132), `sub_822F9498` (90/91) and
|
||||
`sub_822AE628` (81/108) — and finds **277** such functions image-wide.
|
||||
`sub_822AE628` (81/108) — and finds **261** such functions image-wide
|
||||
(**277** before the `r0` correction at the end of this file).
|
||||
|
||||
✅ **The answer: `sub_821A6CF0`, `r29 = 0x820A1630`, 22 of 24 displacements.** In
|
||||
code order it names
|
||||
@@ -204,7 +205,7 @@ HP 42 000 with levels at 25 000 / 10 000 and a lock-on release cycle
|
||||
One record, `Generic`, one field — the **name** `eff_n0071` with an empty value.
|
||||
An effect id and nothing else. Not identified.
|
||||
|
||||
## ✅ Classifying all 277 rows objectively — 53 are data-table schemas (2026-08-27)
|
||||
## ✅ Classifying all rows objectively — 50 are data-table schemas (2026-08-27)
|
||||
|
||||
The earlier pass classified by eye and by function. This one is **by row** and
|
||||
uses an objective test: **are the row's names IDXD record/field names on the
|
||||
@@ -212,8 +213,11 @@ disc?** (13 450 of those disc-wide.) `name_block_bases.py` now prints it.
|
||||
|
||||
| | rows |
|
||||
|---|---:|
|
||||
| **≥50 % disc names, ≥8 names — a data-table schema** | **53** |
|
||||
| everything else (engine/XDK vocabulary, key lists, noise) | 224 |
|
||||
| **≥50 % disc names, ≥8 names — a data-table schema** | **50** |
|
||||
| everything else (engine/XDK vocabulary, key lists, noise) | 211 |
|
||||
|
||||
⚠️ Written as 53 / 224 of 277; the `r0` correction below withdrew 16 rows, three
|
||||
of them from the 53. The two axes below are quoted at their original values.
|
||||
|
||||
Split against the base-confidence axis: `solved` bases (non-zero low half) split
|
||||
34 / 136, `round` bases 16 / 91 — so **a round base is not the same question as a
|
||||
@@ -229,7 +233,7 @@ no `docs/re/` file):
|
||||
| `sub_823BDAA8` r10 | 25 | `Motion_stand`, `Motion_stand_b1`, `Motion_attackA_start`… — **motion names**, the `EnumMotions` family `DefTables` declares |
|
||||
| `sub_82315AE8` r11 | 20 | `InitRotation`, `MaxRotationSpeed`, `RotationAccel`, `MaxVerticalSpeed` — the **`Guardian` record's own fields**, i.e. the S16 boss loader |
|
||||
| `sub_8219E560` r11 | 18 | `Detail_Rank`, `MISSIONS`, `DETAIL_TITLE`, `Detail_Board_Permanent` — the **leaderboard screen** keys |
|
||||
| `sub_825F2CF0` / `sub_825F2F88` r0 | 30 each | `FinalPassBG`, `FinalPassToneRatio`, `FogMin/MaxDistance` — **post-processing**, two functions with the same base |
|
||||
| ~~`sub_825F2CF0` / `sub_825F2F88` r0~~ | ~~30 each~~ | 🔴 **WITHDRAWN — not a name block at all.** See the `r0` correction below |
|
||||
|
||||
⚠️ Four rows that *look* new are not: `sub_82297550`, `sub_822A2F00`,
|
||||
`sub_822A9C18`, `sub_82288028` mix arsenal fields the corpus owns
|
||||
@@ -238,10 +242,10 @@ no `docs/re/` file):
|
||||
coordinates as strings** — `757,228`, `903,343`, `1092,457` — which is why their
|
||||
disc-overlap sits at 53–70 % rather than ~100 %.
|
||||
|
||||
## ✅ Mining the 277: what the base-solver's index actually contains (2026-08-27)
|
||||
## ✅ Mining the index: what the base-solver's index actually contains (2026-08-27)
|
||||
|
||||
277 rows over **190 distinct functions** (a function can read more than one
|
||||
block). Classified:
|
||||
277 rows over **190 distinct functions** — a function can read more than one
|
||||
block — or **261 over 176** after the `r0` correction below. Classified:
|
||||
|
||||
**🔴 The tool's false-positive mode, now named.** 107 rows solve to a base on a
|
||||
**64K boundary** — a bare `addis rX, r0, 0xHHHH` with no `addi` of its own, so any
|
||||
@@ -256,9 +260,9 @@ loader `sub_82341A20` (217), stage settings `sub_8230D1F8` (129), `PlayerParams`
|
||||
(`sub_82320B48` → `ORDER_WINGMAN_*`), missile guidance (`sub_8236B608`,
|
||||
`sub_8237BB78` → `st1_up_aperture` etc., [[weapon-datasheet-static]]), shell
|
||||
movement (`sub_82261F70` → `Spiral_BeginTime`, [[weapon-struct-runtime]]),
|
||||
substructures (`sub_823479B8` → `ParentStructureID`), and six camera/fog readers
|
||||
(`sub_825F2CF0`, `sub_825F2F88`, `sub_8247DFC0`, `sub_823B2620`, `sub_82222E70`,
|
||||
`sub_822C7480`).
|
||||
substructures (`sub_823479B8` → `ParentStructureID`), and ~~six~~ **three** camera/fog readers
|
||||
(`sub_8247DFC0` r31, `sub_823B2620` r31, `sub_822C7480` r31 — all three bases in
|
||||
the same `0x8209E6xx` region; the other three were `r0` artefacts, below).
|
||||
|
||||
**🔑 The find: `sub_8233C368` is the `AIParams` loader.** `r28`, base
|
||||
`0x8208583C`, 20 names — `Enumerate_AIs`, `FiringLength`, `GuardLength`,
|
||||
@@ -289,3 +293,70 @@ positions and look-at tags, with `menu2` having sub-shots `2_0`–`2_4b`.
|
||||
|
||||
🟡 None of those five were opened; the index says what each names, not what each
|
||||
means.
|
||||
|
||||
## 🔴 CORRECTION (2026-08-28) — `r0` is not a base register; 16 rows withdrawn
|
||||
|
||||
The last shortlisted row was `sub_825F2CF0` + `sub_825F2F88`, **`r0`**, 30 names
|
||||
each on the same base `0x8209EB30`, 97 % of them disc names. The question I set
|
||||
was "a pair, or a clone?" **Both answers are wrong: neither function reads a name
|
||||
block.**
|
||||
|
||||
Diffing the two, instruction for instruction, settles it in one look — 145
|
||||
instructions each, **72 differ and every difference is the same substitution**:
|
||||
|
||||
```
|
||||
825F2CF0 addi r11, r0, -288 825F2F88 addi r11, r0, -288
|
||||
825F2CF4 stvx v14, r11, r12 825F2F8C lvx v14, r11, r12
|
||||
825F2CF8 addi r11, r0, -272 825F2F90 addi r11, r0, -272
|
||||
825F2CFC stvx v15, r11, r12 825F2F94 lvx v15, r11, r12
|
||||
… stvx / stvx128, v14 … v127 … lvx / lvx128, v14 … v127
|
||||
```
|
||||
|
||||
They are the compiler's **VMX register save / restore helper pair** — a spill of
|
||||
v14–v127 and its matching reload. So they *are* a pair rather than a clone, but
|
||||
the pairing is `stvx`/`lvx`, not two readers of one table.
|
||||
|
||||
🔑 **The root cause, and it is a class of false positive, not one row.** In
|
||||
PowerPC `addi rD, rA, N` the `rA` slot **reads as literal zero when it names r0** —
|
||||
the form is `li rD, N`. The 72 `addi r11, r0, -N` are the vector spill offsets,
|
||||
plain immediates. The solver had excluded `r1` (the stack pointer) and nothing
|
||||
else, so it took those offsets as displacements, voted a base, and landed
|
||||
`0x8209EB30` — **inside the stage-settings name block**, where a scatter of
|
||||
16-byte-spaced negative offsets is dense enough to "resolve" 30 real field names.
|
||||
|
||||
**A 97 %-disc-names row can still be an artefact.** The disc-name test measures
|
||||
what the *base region* contains, not that the function reads it.
|
||||
|
||||
✅ **Nothing is lost.** All 30 of the withdrawn names are a **strict subset of the
|
||||
real reader's block**: `sub_8230D1F8 r29`, base `0x8209FD28`, 129 names —
|
||||
the stage-settings loader the corpus already owns ([[stage-settings-table]]).
|
||||
The string-xref join confirms it independently: `FinalPassBG`, `FogMinDistance`,
|
||||
`ScreenColorR`, `ExposureKey_BeginValue` each exist **once** in the image and
|
||||
each has **exactly one** xref, from `sub_8230D1F8`. `NoseCameraFOV` and
|
||||
`GlareType` exist **twice** — the second copy is read by `sub_822AE628`, the
|
||||
hangar's game-wide defaults, which is the trap the corpus already records.
|
||||
|
||||
**Fix and its effect.** `name_block_bases.py` now skips `reg in ('r0', 'r1')`.
|
||||
Every number moves by exactly the 16 `r0` rows and nothing else:
|
||||
|
||||
| | before | after |
|
||||
|---|---:|---:|
|
||||
| rows | 277 | **261** |
|
||||
| distinct functions | 190 | **176** |
|
||||
| bases with a non-zero low half | 170 | **154** |
|
||||
| bases on a 64K boundary (low confidence) | 107 | 107 |
|
||||
| data-table schemas (≥50 % disc, ≥8 names) | 53 | **50** |
|
||||
|
||||
Both ways: `154 + 107 = 261`, and `277 − 16 = 261`. The diff against the previous
|
||||
artefact removes 100 lines and adds 3; **every removed row line carries `r0`**,
|
||||
the three added lines are those counts, and the control is untouched
|
||||
(`sub_82341A20 r30 = 0x82088F94`, 217/226). Two of the 16 functions keep a row
|
||||
through another register, which is why 190 − 176 = 14, not 16.
|
||||
|
||||
The three withdrawn data-table rows are `sub_825F2CF0`, `sub_825F2F88` and
|
||||
`sub_82222E70` (15 names, 100 % disc — the same `0x8209E6D8` stage-settings
|
||||
region, and by the same mechanism).
|
||||
|
||||
🟡 What this does **not** settle: the 🟡 stalled `SpaceSize` / `GlareType` /
|
||||
`Nebura_*` numerics are no closer — their reader was already known to be
|
||||
`sub_8230D1F8`, and the r0 row never was a second one.
|
||||
|
||||
@@ -57,7 +57,13 @@ def main():
|
||||
for name in sorted(byf):
|
||||
for reg in sorted(byf[name]):
|
||||
D = sorted(set(byf[name][reg]))
|
||||
if len(D) < MIN_GROUP or reg == 'r1': # r1 is the stack pointer
|
||||
# r1 is the stack pointer. r0 is NOT a base register at all: in
|
||||
# `addi rD, r0, N` the RA slot reads as literal zero, so the form is
|
||||
# `li rD, N` and the displacements are plain immediates. Left in, the
|
||||
# VMX save/restore helper pair sub_825F2CF0 / sub_825F2F88 (72 x
|
||||
# `addi r11, r0, -N`, the vector spill offsets) solved a base and
|
||||
# "named" 30 strings, 97% of them disc names -- a pure artefact.
|
||||
if len(D) < MIN_GROUP or reg in ('r0', 'r1'):
|
||||
continue
|
||||
# Vote: every (string, displacement) pair implies one candidate base.
|
||||
# The true base collects a vote from each name it explains, so it wins
|
||||
|
||||
Reference in New Issue
Block a user