Skip to content

overlay: match five level functions, apply Naming Desk names and define level data - #212

Merged
mateuszklysz merged 40 commits into
mainfrom
decomp/wave-49i66q
Oct 18, 2026
Merged

mateuszklysz merged 40 commits into
mainfrom
decomp/wave-49i66q

Conversation

@mateuszklysz

@mateuszklysz mateuszklysz commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

Before

Several level functions were still retail asm (INCLUDE_ASM): the trackdrive pickup update, the hero update with the vehicle mode 3 glow, the walloper beam reset, the menu icon cache lookup and a HUD counter. Hundreds of symbols still had FUN_/D_ names that the Naming Desk had already settled. Most zero-filled level data had no C definition, and dmaRefImage had no source.

After

  • Matched in C: FUN_L02_002ea210 (trackdrive pickup update), FUN_L01_00228000 (hero update), FUN_L00_002bcf98 (walloper beam reset), FUN_L00_00249d80 (menu icon cache lookup) and FUN_L05_00266320 (HUD counter). The last two carry Fakematch: comments for register-allocation tricks.
  • Boot: added the dmaRefImage source. The sceFsInit draft now differs only in the prologue save order.
  • Names:
    • Applied the high-probability Naming Desk names across boot/SDK, shared gameplay, math, rendering/UI/audio/world and levels 0-18.
    • Proposals that were only address-suffixed local aliases (f2334d0_2133a8, ea210_*, *302618, spin_s, ...) were dropped. Those calls keep their retail FUN_ label.
    • Level-tagged and _cf aliases bound to other functions (activate_effect_l08, allocate_voice_for_target_entry_cf, ...) were not spread, and class update names two functions of one level share (rocket_update in level 13) were left as labels.
    • FUN_L00_0025e310 is normalize_angle (wraps into -pi..pi). The timer and xy length helpers use the names most files give them (fast_dec_timer, vector_length_xy).
    • Local aliases that a name would have bound to a different function (for example scale_time for FUN_L04_001f1978) now use the label they really call.
    • New C functions name their locals by use.
  • Data:
    • Zero level data objects are now defined in the file that reads them. Objects that may be elements of an unsized or declared array were taken back to asm.
    • Seven debug strings are now literals.
    • Mesh tables for the conveyor belt, the level 17 door and fred are defined, each sized by its loop or face count.
  • Fixes:
    • Uncached-mirror immediates are written as numbers in the expected asm.
    • Calls inside a unit keep their relocation in raw oracles.
    • Three exact boot functions are bound to their retail symbol names.
    • Non-matching drafts compile again after the naming pass.

Verification

  • make elf ends with PASS: reconstructed boot ELF matches retail
  • make overlays ends with PASS (overlay changes)
  • make check passes

The NON_MATCHING draft missed by one float register. The rac1-decomp
order fixes it: 0.2f in a local set before the if, the 0x40 store before
the 0x44 store, the height sum stored before the state byte.
No code reaches these spans by address; they are zero in all 19 levels,
so each is one label-named array in level_globals.c with a data.tsv row
(53,636 bytes, checked in every level).
…them

Each object starts at an address code reaches and ends at the next one;
every function that reaches it lives in one src/overlays file, so the
object is defined there (label name, element type from the access width,
section(".data") for 8 bytes or less). 477,156 bytes, all zero in retail,
checked by make overlays.
Each was an unsized extern that only one file reads. Its size is the
span to the next address code reaches, in whole elements of the declared
type; data-refs.py --emit wrote the values (pointers as symbols). Objects
whose extern sits in a NON_MATCHING draft are defined after the draft.
284,209 bytes, checked by make overlays.
Their externs were unsized; the sizes came from the span to the next
address code reaches, which docs/code-cleanup.md forbids (never guess a
size), and 88 of them were byte arrays. The data stays in assembly.
Each span was sized from the gap to the next symbol and may hold several variables; shared data stays in assembly.
2,936 zero objects whose length came from the gap to the next symbol, or whose type was unknown (u8), go back to assembly. The 2,377 kept ones take their type from the reading code and are one element, so no size is guessed.
…unsized array

Each sat a few bytes past a label the code reads as an array of unknown size, so it may be an element of that array rather than its own variable.
Three meshes of 68, 46 and 88 vertices: source positions and UVs, then the moved positions, UVs and colours; each table ends where the next begins.
Face counts come from the draw loops (864, 58, 50); vertex and UV counts are one more than the largest index in each face table, and every table ends where the next one starts. The per-face vectors are float[4], not bytes.
end_display, read_buf_end_get and the VIF1 DMA handler were byte-exact, but the report could not pair them with the expected objects (ClearStageStateFlag, GetStateTableWord, func_00233E00), so they counted as unmatched.
A raw-word oracle had no relocation for a jal to a function of the same unit, so a recursive call differed from our object only in its relocation and the function never counted as matched.
The renames gave two prototypes of one function different types, so the
NON_MATCHING drafts in five files stopped compiling. The snagglebeast
update draft also comes closer to retail.
Two plain loops replace the pointer-walking draft. The HUD draft for
FUN_L05_00266320 drops its pointer trick at the same distance.
@mateuszklysz mateuszklysz added the enhancement New feature or request label Oct 17, 2026 — with Claude
@github-actions

Copy link
Copy Markdown

Decompilation progress

C_EXACT Change Matched bytes Functions C_FUZZY
All code 93.48 % +0.12 pp 3,316,916 / 3,548,100 B (+4,316 B) 4,101 / 4,246 (+6) 94.68 %
Boot executable 86.36 % +0.10 pp 306,304 / 354,672 B (+364 B) 1,183 / 1,232 (+1) 98.37 %
Game 85.10 % — 232,860 / 273,636 B (—) 876 / 912 (—) 98.49 %
SDK 90.63 % +0.45 pp 73,444 / 81,036 B (+364 B) 307 / 320 (+1) 97.94 %
Level overlays 94.28 % +0.12 pp 3,010,612 / 3,193,428 B (+3,952 B) 2,918 / 3,014 (+5) 94.28 %
Shared level code 88.45 % +0.35 pp 999,972 / 1,130,492 B (+3,952 B) 1,506 / 1,583 (+5) 88.45 %
Per-level code 97.46 % — 2,010,640 / 2,062,936 B (—) 1,412 / 1,431 (—) 97.46 %
Data in C Change Matched bytes
All data 43.58 % +0.77 pp 5,418,137 / 12,433,372 B (+95,660 B)
Boot executable 2.29 % — 16,042 / 699,136 B (—)
Level overlays 46.04 % +0.82 pp 5,402,095 / 11,734,236 B (+95,660 B)
6 newly matched functions (4,316 B)
Function Address Size Unit
FUN_L02_002ea210 0x002ea210 1,468 B shared/gameplay/entities/trackdrive_left
FUN_L05_00266320 0x00266320 1,004 B shared/ui/hud/002661a0
FUN_L01_00228000 0x00228000 932 B shared/gameplay/hero/air_accel
dmaRefImage 0x0002af38 364 B sdk/dma
FUN_L00_00249d80 0x00249d80 288 B shared/ui/menus/00248d08
FUN_L00_002bcf98 0x002bcf98 260 B shared/gameplay/entities/walloper

Compared with main (d893976). C_FUZZY uses main's last measurement.

@mateuszklysz
mateuszklysz marked this pull request as ready for review October 17, 2026 22:43
…wrap

Level-suffixed and _cf aliases bound to other functions go back to the retail labels, as do class update names two functions in one level shared. FUN_L00_0025e310 wraps an angle into -pi..pi, so it becomes normalize_angle.
tick_countdown_32 and vec_len_xy spread by the naming pass become fast_dec_timer (the unit's own file name) and vector_length_xy, the names most files already use. Two hero_set_state lines go back to the plain label so the non-matching drafts compile.
@mateuszklysz mateuszklysz changed the title overlay: match five level functions, apply 663 Naming Desk names and define level data overlay: match five level functions, apply Naming Desk names and define level data Oct 17, 2026
@mateuszklysz
mateuszklysz merged commit 013055a into main Oct 18, 2026
6 checks passed
@mateuszklysz
mateuszklysz deleted the decomp/wave-49i66q branch October 18, 2026 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant