[{"timestamp":"2026-10-15T03:45:11Z","commit_sha":"3b302f041223acb7a825c0b2ccc898fd24b0aa7f","commit_message":"docs: link the README progress badge and map to bytematch.dev (#185)","measures":{"fuzzy_match_percent":89.69617,"total_code":3546268,"matched_code":3136836,"matched_code_percent":88.45457,"total_data":12433372,"matched_data":4017559,"matched_data_percent":32.312706,"total_functions":4233,"matched_functions":3980,"matched_functions_percent":94.02315,"complete_code":3136836,"complete_code_percent":88.45457,"complete_data":4017559,"complete_data_percent":32.312706,"total_units":513,"complete_units":402}},{"timestamp":"2026-10-15T02:46:57Z","commit_sha":"6113df75a0c1d8d735ab206e3622844e3a54ef17","commit_message":"overlay: one declaration per placement for three data labels (#184)","measures":{"fuzzy_match_percent":89.69617,"total_code":3546268,"matched_code":3136836,"matched_code_percent":88.45457,"total_data":12433372,"matched_data":4017559,"matched_data_percent":32.312706,"total_functions":4233,"matched_functions":3980,"matched_functions_percent":94.02315,"complete_code":3136836,"complete_code_percent":88.45457,"complete_data":4017559,"complete_data_percent":32.312706,"total_units":513,"complete_units":402}},{"timestamp":"2026-10-15T02:45:07Z","commit_sha":"ae032415ebbd4147e3fe65926c4da8254fb666e7","commit_message":"config: list Lombyte on recomp.fyi instead of decomp.dev (#183)","measures":{"fuzzy_match_percent":89.69617,"total_code":3546268,"matched_code":3136836,"matched_code_percent":88.45457,"total_data":12433372,"matched_data":4017559,"matched_data_percent":32.312706,"total_functions":4233,"matched_functions":3980,"matched_functions_percent":94.02315,"complete_code":3136836,"complete_code_percent":88.45457,"complete_data":4017559,"complete_data_percent":32.312706,"total_units":513,"complete_units":402}},{"timestamp":"2026-10-15T02:42:35Z","commit_sha":"0b02b7478b5acddb0edd7a353c7ac606d4da1bd7","commit_message":"decomp: give 104 data labels one name each (#182)","measures":{"fuzzy_match_percent":89.69617,"total_code":3546268,"matched_code":3136836,"matched_code_percent":88.45457,"total_data":12433372,"matched_data":4017559,"matched_data_percent":32.312706,"total_functions":4233,"matched_functions":3980,"matched_functions_percent":94.02315,"complete_code":3136836,"complete_code_percent":88.45457,"complete_data":4017559,"complete_data_percent":32.312706,"total_units":513,"complete_units":402}},{"timestamp":"2026-10-14T18:33:28Z","commit_sha":"6db3f5530caf1b0276981611e8697ad3cda04b01","commit_message":"decomp: promote 13 overlay functions and refine guarded C (#180)\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L15_001ff938\n\n* decomp: improve FUN_L00_0020f160\n\n* decomp: improve FUN_L06_002d8738\n\n* decomp: improve FUN_L15_002a3138\n\n* decomp: improve initialize_level_graphics_frame_effect_state\n\n* decomp: improve FUN_L00_002caf70\n\n* decomp: improve FUN_L10_002da690\n\n* decomp: improve FUN_L15_002a3138\n\n* decomp: improve FUN_L12_002bf140\n\n* decomp: improve FUN_L15_001ff938\n\n* decomp: improve FUN_L12_00308350\n\n* decomp: improve FUN_L13_00306300\n\n* decomp: improve FUN_L15_001ff938\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve FUN_L10_002da690\n\n* decomp: improve FUN_L18_002e9768\n\n* decomp: improve spawn_troll_alert_particles\n\n* decomp: improve FUN_L01_002eec68\n\n* decomp: improve FUN_L00_0020dd20\n\n* decomp: improve update_motion_and_emit_effects\n\n* decomp: improve FUN_L07_0030d4d8\n\n* decomp: improve spawn_troll_alert_particles\n\n* decomp: improve FUN_L18_002e9768\n\n* decomp: improve FUN_L00_002d73e8\n\n* decomp: improve FUN_L05_002d1688\n\n* decomp: improve FUN_L01_002eec68\n\n* decomp: improve update_hero_held_items_and_orientation\n\n* decomp: improve update_moby_state_and_emit_effects\n\n* decomp: improve FUN_L00_002062b0\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve update_spawned_moby\n\n* decomp: improve FUN_L00_002cd1f0\n\n* decomp: improve FUN_L08_002dabf0\n\n* decomp: improve FUN_L00_002dbf28\n\n* decomp: improve FUN_L07_0030cf90\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve update_spawned_moby\n\n* decomp: improve update_hero_held_items_and_orientation\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve FUN_L06_002e8678\n\n* decomp: improve FUN_L00_002c4380\n\n* decomp: improve FUN_L12_002e9f68\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve update_help_effect\n\n* decomp: improve update_linked_moby_path_transition\n\n* decomp: improve FUN_L01_002f5168\n\n* decomp: improve FUN_L08_002dabf0\n\n* decomp: improve FUN_L00_002d73e8\n\n* decomp: improve FUN_L06_002f9a28\n\n* decomp: improve FUN_L02_002d93e8\n\n* decomp: improve FUN_L12_002e9f68\n\n* decomp: improve FUN_L00_002c26c8\n\n* decomp: improve FUN_L01_002ef350\n\n* decomp: improve FUN_L06_002f5d78\n\n* decomp: improve FUN_L00_002c1ad0\n\n* decomp: improve FUN_L06_002e8678\n\n* decomp: improve FUN_L12_002e9f68\n\n* decomp: improve FUN_L12_00308350\n\n* decomp: improve FUN_L07_0030d4d8\n\n* decomp: improve FUN_L00_002ce358\n\n* decomp: improve update_help_effect\n\n* decomp: improve FUN_L06_002f5d78\n\n* decomp: improve draw_quad_grid_with_dynamic_uvs\n\n* decomp: improve FUN_L02_002d93e8\n\n* decomp: improve FUN_L00_002ddf60\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L08_002f5e58\n\n* decomp: improve FUN_L12_002e9f68\n\n* decomp: improve FUN_L00_002caf70\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L06_002f5d78\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve FUN_L12_002e9f68\n\n* decomp: improve FUN_L00_002d9810\n\n* decomp: improve FUN_L01_002f5168\n\n* decomp: improve scan_hero_input_sequences\n\n* decomp: improve FUN_L05_002d1688\n\n* decomp: improve FUN_L02_002d93e8\n\n* decomp: improve FUN_L00_002caf70\n\n* decomp: improve FUN_L07_00311eb8\n\n* decomp: improve update_linked_moby_path_transition\n\n* decomp: improve FUN_L12_002e9f68\n\n* decomp: improve FUN_L08_002f5e58\n\n* decomp: improve FUN_L00_002caf70\n\n* decomp: improve FUN_L12_002e72c0\n\n* decomp: improve FUN_L06_002e8678\n\n* decomp: improve FUN_L02_002d93e8\n\n* decomp: improve FUN_L06_002f9a28\n\n* decomp: improve FUN_L00_002ddf60\n\n* decomp: improve scan_hero_input_sequences\n\n* decomp: improve FUN_L00_002d19b0\n\n* decomp: improve FUN_L00_002c89e8\n\n* decomp: improve FUN_L07_0030cf90\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L01_002f5168\n\n* decomp: improve FUN_L05_002d1688\n\n* decomp: improve FUN_L08_002f5e58\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve update_linked_moby_path_transition\n\n* decomp: improve FUN_L00_002d9810\n\n* decomp: improve FUN_L02_002d93e8\n\n* decomp: improve FUN_L08_002e3870\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L06_002f9a28\n\n* decomp: improve FUN_L00_002062b0\n\n* decomp: improve FUN_L00_002d9810\n\n* decomp: improve FUN_L05_002d1688\n\n* decomp: improve FUN_L00_0020dd20\n\n* decomp: improve FUN_L01_002f5168\n\n* decomp: improve FUN_L00_002bffa8\n\n* decomp: improve FUN_L08_002f5e58\n\n* decomp: improve FUN_L00_002cd1f0\n\n* decomp: improve update_linked_moby_path_transition\n\n* decomp: improve FUN_L05_002d1688\n\n* decomp: improve FUN_L00_0020f160\n\n* decomp: improve FUN_L08_002e3870\n\n* decomp: improve FUN_L01_002f5168\n\n* decomp: improve FUN_L00_002d2158\n\n* decomp: improve FUN_L00_002062b0\n\n* decomp: improve FUN_L00_002c1ad0\n\n* decomp: improve FUN_L00_0020dd20\n\n* decomp: improve FUN_L08_002f5e58\n\n* decomp: improve FUN_L07_0030f5f0\n\n* decomp: improve FUN_L06_002f9a28\n\n* decomp: improve FUN_L01_002f5168\n\n* decomp: improve update_help_effect\n\n* decomp: improve FUN_L00_002c1ad0\n\n* decomp: improve FUN_L08_002f5e58\n\n* decomp: improve FUN_L00_002ce358\n\n* decomp: improve FUN_L00_0020dd20\n\n* decomp: improve FUN_L00_002062b0\n\n* decomp: improve FUN_L01_002edca0\n\n* decomp: improve FUN_L07_0030b000\n\n* decomp: improve FUN_L06_002f9a28\n\n* decomp: improve FUN_L00_002d2158\n\n* decomp: improve FUN_L00_002bffa8\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L01_002edca0\n\n* decomp: improve FUN_L00_002ce358\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L06_002f9a28\n\n* decomp: improve FUN_L07_0030d4d8\n\n* decomp: improve FUN_L00_002d73e8\n\n* decomp: improve FUN_L01_002edca0\n\n* decomp: improve FUN_L00_002bffa8\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L07_0030b000\n\n* decomp: improve FUN_L00_002ce358\n\n* decomp: improve FUN_L01_002edca0\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L00_002bffa8\n\n* decomp: improve FUN_L00_002ce358\n\n* decomp: improve FUN_L00_002cfcb8\n\n* decomp: improve FUN_L07_0030f5f0\n\n* decomp: improve FUN_L00_002bffa8\n\n* decomp: improve FUN_L00_002c97e0\n\n* decomp: improve FUN_L00_002cfcb8\n\n* decomp: improve FUN_L00_002bffa8\n\n* decomp: improve FUN_L00_002c97e0\n\n* decomp: improve FUN_L07_0030f5f0\n\n* decomp: improve FUN_L00_002c97e0\n\n* decomp: improve FUN_L07_0030f5f0\n\n* decomp: improve FUN_L07_0030f5f0\n\n* decomp: improve FUN_L00_002cfcb8\n\n* decomp: improve FUN_L00_002598b0\n\n* decomp: improve FUN_L00_002a96f8\n\n* decomp: improve FUN_L03_00250ae8\n\n* decomp: improve FUN_L07_00312948\n\n* decomp: improve FUN_L06_00303748\n\n* decomp: improve FUN_L12_003064e8\n\n* decomp: improve FUN_L15_002cb4c8\n\n* decomp: improve FUN_L00_00236e50\n\n* decomp: improve FUN_L10_002e3a90\n\n* decomp: improve FUN_L06_002f2c28\n\n* decomp: improve FUN_L18_002ea800\n\n* decomp: improve FUN_L00_002e2c88\n\n* decomp: improve FUN_L13_003073c8\n\n* decomp: improve FUN_L15_002c2938\n\n* decomp: improve FUN_L13_002c25b8\n\n* decomp: improve FUN_L08_002d5d08\n\n* decomp: improve FUN_L14_002b17d8\n\n* decomp: improve FUN_L00_00264740\n\n* decomp: improve FUN_L05_00304320\n\n* decomp: improve FUN_L12_003054b0\n\n* decomp: improve FUN_L15_002a6e68\n\n* decomp: improve FUN_L07_00317e60\n\n* decomp: improve FUN_L15_002d6810\n\n* decomp: improve FUN_L10_002e4a88\n\n* decomp: improve FUN_L08_002d42d8\n\n* decomp: improve FUN_L15_002c5630\n\n* decomp: improve FUN_L06_00303748\n\n* decomp: improve FUN_L03_00250ae8\n\n* decomp: improve FUN_L15_002a3138\n\n* decomp: improve FUN_L00_00236e50\n\n* decomp: improve FUN_L18_002ea800\n\n* decomp: improve FUN_L10_002e5be0\n\n* decomp: improve FUN_L07_00312948\n\n* decomp: improve FUN_L15_002d0fa8\n\n* decomp: improve FUN_L13_003073c8\n\n* decomp: improve FUN_L13_002c25b8\n\n* decomp: improve FUN_L00_002e2c88\n\n* decomp: improve FUN_L14_002b2928\n\n* decomp: improve generate_random_points_from_shape_entries\n\n* decomp: improve FUN_L15_002a3138\n\n* decomp: improve FUN_L15_002d0fa8\n\n* decomp: improve update_linked_moby_path_transition\n\n* decomp: improve FUN_L00_00236e50\n\n* decomp: improve FUN_L08_002d42d8\n\n* decomp: improve FUN_L15_002cb4c8\n\n* decomp: improve FUN_L15_002d6810\n\n* decomp: improve FUN_L10_002e3a90\n\n* decomp: improve FUN_L13_003073c8\n\n* decomp: improve FUN_L12_003064e8\n\n* decomp: improve FUN_L08_002d23f0\n\n* decomp: improve FUN_L15_002d6810\n\n* decomp: improve FUN_L15_002a7880\n\n* decomp: improve FUN_L07_00312948\n\n* decomp: improve FUN_L10_002e5be0\n\n* decomp: improve FUN_L13_003073c8\n\n* decomp: improve FUN_L14_002b17d8\n\n* decomp: improve FUN_L15_002d6810\n\n* decomp: improve FUN_L07_00312948\n\n* decomp: improve FUN_L13_003073c8\n\n* decomp: improve FUN_L12_003054b0\n\n* decomp: improve FUN_L08_002d5d08\n\n* decomp: improve FUN_L15_002c5630\n\n* decomp: improve FUN_L15_002d6810\n\n* decomp: improve register_object_render_class\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve font_print_window\n\n* decomp: improve FUN_L05_0030de90\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve FUN_L06_00307578\n\n* decomp: improve FUN_L00_001fc558\n\n* decomp: improve FUN_L05_00255208\n\n* decomp: improve print_sorted_moby_sizes\n\n* decomp: improve FUN_L14_00301de8\n\n* decomp: improve FUN_L00_002b94d0\n\n* decomp: improve FUN_L00_002995d0\n\n* decomp: improve FUN_L05_00255208\n\n* decomp: improve FUN_L14_00301de8\n\n* decomp: improve FUN_L08_00316fa8\n\n* decomp: improve FUN_L05_00255208\n\n* decomp: improve FUN_L08_002e2250\n\n* decomp: improve FUN_L06_00307578\n\n* overlay: align batch 16 types and aliases with main\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":89.69617,"total_code":3546268,"matched_code":3136836,"matched_code_percent":88.45457,"total_data":12433372,"matched_data":4017559,"matched_data_percent":32.312706,"total_functions":4233,"matched_functions":3980,"matched_functions_percent":94.02315,"complete_code":3136836,"complete_code_percent":88.45457,"complete_data":4017559,"complete_data_percent":32.312706,"total_units":513,"complete_units":402}},{"timestamp":"2026-10-14T16:27:09Z","commit_sha":"9745b8624dc0a86d8653b9ff6f222ba74299e45f","commit_message":"decomp: data in C, checked byte for byte in the boot ELF and every level (#179)\n\n* fix: action 1 of the menu list does nothing, like action 0\n\nThe retail switch table at 0x1E8770 sends action 1 to the same place as\naction 0 (break), not to the action 3 arm. The code bytes were the same\neither way, and the preserved core_rdata blob hid the wrong table entry.\n\n* config: link the data C units own in place of the blob bytes\n\nThe .rodata, .sdata and .data of the units in RODATA_OVERLAYS,\nSDATA_OVERLAYS and DATA_OVERLAYS used to be linked on top of the\npreserved blobs, and the blob bytes won. A wrong value in C still gave\nPASS, and data in a unit no table listed was dropped without a word.\n\nEach entry now also gives its size. The blobs are linked as the pieces\nbetween the C-owned ranges, so the gate hashes what the C compiled to.\nThe link fails when a C section is not its configured size, when an\nentry names no configured unit, and when a unit defines data no entry\nplaces. render_level_effects_and_screen_sprites gets back the entry for\nits panel slot table, left under the unit's old name.\n\n* overlay: prove the level data defined in C\n\nA D_LNN_XXXXXXXX object defined in src/overlays is compared with what\nlevel NN loads at XXXXXXXX, every pointer in it resolved to that level's\naddress of its symbol (check_data, overlay-data-bytes-v1). make overlays\nruns it for every data object in C, fails on data without a D_LNN label,\nand checks config/overlays/us/data.tsv lists each one with its size.\n\n* config: count data in the progress report\n\ntotal_data is the executable's preserved data and each level's .lit,\n.data and vtables; matched_data is the data C defines and a proof checks:\nthe *_OVERLAYS entries (the boot gate) and config/overlays/us/data.tsv\n(make overlays). bss is not counted.\n\n* config: let C units define the boot bss; --emit writes level data\n\nBSS_OVERLAYS (VMA, size) and SBSS_OVERLAYS (VMA, offset, size) place a\nunit's uninitialised variables; the preserved bss is linked as the pieces\naround them and drops the splat labels the unit now defines. bss has no\nfile bytes, so the gate also checks that every D_/FUN_/jtbl_ label is\nlinked at its own address. Common symbols link with their unit's bss.\n\ndata-refs.py --emit now covers every boot data section (const for\ncore_rdata, section(\".bss\") for bss) and, with --level N, level data:\nvalues from the level's records, pointers named after the level's\nfunctions and data, and the row added to config/overlays/us/data.tsv.\nA level's small bss sits in its .lit as zeros; the data proof accepts it.\n\n* overlay: first level data in C, the l18 sparkle quad corners and uvs\n\ndata-refs --emit now prints the shortest exact float, one row per line\nfor nested arrays, and turns an extern in the target file into the\ndefinition.\n\n* config: one type per global for the three boot globals C defines\n\nsnd_current_buffer, frm_clock_time and vif_chain_flags were declared\nwith another type than their definition; D_0015EC80 also sat in\nundefined_syms.txt, which overrides the C definition.\n\n* decomp: one name per data label, drop the duplicate externs\n\nEvery D_ label now has one declaration with one name: plain local\nexterns that repeat a header or another file are removed and their uses\nrenamed. A label used by several files is declared once in\ninclude/rnc/data_labels.h (boot) or include/rnc/overlay/level_labels.h\n(levels) until its subsystem is known.\n\nPlacements stay as they were: a file that reaches a label with sda,\nNOT_SDA or MACRO_ADDR keeps one alias for it, named <name>_gp, _lui or\n_macro when the plain name is also visible. A function that reads a\nlabel through two names keeps both (the second name is a lever).\n\nLabels whose declarations disagree on the type are left for the next\nstep.\n\n* chore: check that no data label gets a second type or name\n\nscripts/data-decls.py lists the D_ labels that src/ and include/ declare\nwith more than one type or name (placement aliases _gp, _lui and _macro\ncount as one name). make check fails when the count grows; it is lowered\nas each label is typed by hand.\n\n* decomp: one signedness per data label\n\nSemaphore ids (sceCd, sceMc) are s32: they are compared with -1 and < 0.\ncreate_moby compares spawn_frame with the frame counter unsigned, so it\ncasts there instead of changing the counter's type.\n\n* decomp: give address-only array externs the element type the indexing code uses\n\n* decomp: drop data externs their file never uses\n\n002deee0.c keeps its list: removing it changes the unit's code.\n\n* decomp: one name per data label where the types already agree\n\nEach file's alias takes the label's real name, plus _gp, _lui or _macro\nwhen the file needs another placement.\n\n* decomp: one name per data label inside files that used several\n\n* chore: no space before the semicolon of extern lines\n\n* decomp: header data labels take their real name too\n\n* decomp: externs only used through their address take the type the reading code uses\n\n* decomp: one name per data label for the labels that now share a type\n\n* decomp: drop more unused data externs\n\n* config: show data in C on the progress map and in decomp_map.json\n\n* fix: progress map skips data when the tree has no executable config\n\n* config: shorter C_EXACT caption, data stat closer on the progress map\n\n* docs: data in the progress map; drop a stale linkage comment\n\n* config: data-refs --emit finds externs named by their label and goes on past a failed address\n\n* config: data every level holds at one address (D_XXXXXXXX) is proven in all levels and counted in each\n\n* overlay: define in C the level data only one level file reads (430 objects)\n\nThe proof resolves a reference to data the file itself defines (the\nassembler points at the section, gp-relative offsets minus gp0).\n\n* overlay: zero globals every level holds at the same address, defined once and proven in all levels\n\n* config: decomp_map.json and the map tooltip say how much of the data in C is zeros\n\n* docs: level data rows without a level, and the zero share\n\n* docs: code-cleanup.md covers data in C\n\n* decomp: data names from their readers, one name per label\n\n* docs: CONTRIBUTING.md covers moving data to C\n\n* config: progress map shows data in C above the code percentage\n\n* config: progress map captions read 'data in C' and 'exe + overlays in C'\n\n* decomp: level data read as int is int, with its retail value, in levels 10-18\n\n* config: progress map leads with exe + overlays in C, data in C above it\n\n* config: progress map cuts the boot drawer at 3/4, whole-game figures right of the cut\n\n* decomp: level data l10-l18 at its real size, pointer tables as pointers\n\nHero step tables are int[4] in .sdata and the unk3E4 pointee is a\nHeroVelocityKey; l16/l17 vertex count and vertex pointer tables hold their\ncounts and point at the named level data; offset vectors read by index are\nfloat[4].\n\n* decomp: level data l00-l09 at its real size, pointer tables as pointers\n\nHero step tables (0015F6D8, L05 0015F6E8) are int[4] in .sdata, the\n0015F6E8 pointee is the char[4] the shared hero code declares, the l02\nshorts read as ints are ints, the l02 offset vector is float[4], and the\nl08 vertex/colour tables point at their named level data. Scalars drop the\n{0} braces; l07 scroll phase no longer shadows its local.\n\n* decomp: hero velocity key pointee is a HeroVelocityKey in levels 01-08\n\n* config: progress map gives both figures a light frosted plate, executable in C caption\n\n* config: progress map drops the header band and dims the boot treemap\n\n* config: progress map shows both figures at one size, plain boot label\n\n* config: progress map tightens the gap under data in C\n\n* config: progress map dims the boot treemap a little more\n\n* decomp: named globals live in their subsystem headers, data_labels.h keeps D_ labels only\n\n* config: data.tsv rows sorted by name\n\n* config: progress map panel uses the boot treemap's brown\n\n* config: progress map boot plate uses the panel's brown\n\n* config: progress map boot figure sits on the panel's own face, hatching and glow\n\n* config: progress map boot figure keeps only the panel's glow\n\n* config: progress map darkens the centre behind the boot figure\n\n* config: _sceFs_Rcv_Intr .rodata is its 100-byte switch table now that it is C\n\n* decomp: single zero values as 0, header titles dropped, level labels by address\n\n* chore: data scripts count both zero forms, unused map locals dropped\n\n* docs: data docs wrapped, migrated tables noted in configure.py\n\n* docs: HeroVelocityKey comment names frame_time_sq and the -999999 keep value\n\n* config: PR progress comment shows the change in data in C","measures":{"fuzzy_match_percent":89.02808,"total_code":3546268,"matched_code":3113144,"matched_code_percent":87.78648,"total_data":12433372,"matched_data":4017559,"matched_data_percent":32.312706,"total_functions":4233,"matched_functions":3967,"matched_functions_percent":93.71604,"complete_code":3113144,"complete_code_percent":87.78648,"complete_data":4017559,"complete_data_percent":32.312706,"total_units":513,"complete_units":400}},{"timestamp":"2026-10-14T15:15:29Z","commit_sha":"5fe15c82dacb7dbb2423e3afd8dc9dfb51bfd71f","commit_message":"fix: place select_world_object_resource_tables data after its promotion (#178)\n\nThe unit moved out of assembly/, but its DATA_OVERLAYS key kept the old\npath, so its .data (class_material_maps, 0x480 B) was discarded at link\ntime and the retail blob supplied those bytes. Rename the key so the\nsection is placed at 0x1CBBE0 again, and drop the duplicate includes left\nfrom the old #else body.","measures":{"fuzzy_match_percent":89.02808,"total_code":3546268,"matched_code":3113144,"matched_code_percent":87.78648,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3967,"matched_functions_percent":93.71604,"complete_code":3113144,"complete_code_percent":87.78648,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":400}},{"timestamp":"2026-10-14T15:09:59Z","commit_sha":"ce3909167bb1519cd24de644636e68ee23666977","commit_message":"decomp: promote _printf, select_world_object_resource_tables and _sceFs_Rcv_Intr (3100 B) (#177)\n\n* decomp: promote _printf (1516 B)\n\ncheck-unit reports Object matches (promotable). The C body's format\nswitch emits its jump table in .rodata, so pin it at retail's\njtbl_001527B0 (0x1527B0, file 0x53730) in RODATA_OVERLAYS, right after\nprintfloat's literals; without the pin the linker discards it.\n\n./verify-baseline.sh: PASS: reconstructed boot ELF matches retail\n\n* decomp: promote select_world_object_resource_tables (684 B)\n\nThe two hoisted %hi registers (resident_class_slot_by_id, moby_class_resources)\ncame out in s0/s4 swapped. Global alloc ranks them by refs/live length and\nthen by pseudo number, which PRE assigns in GCSE hash order of the symbol\nstring. Reading class_slot before taking the table base equalises the live\nlengths, and naming the table D_001B3200 without the asm-label prefix puts its\n%hi first in the hash order, which gives retail's allocation.\n\n./verify-baseline.sh: PASS: reconstructed boot ELF matches retail\n\n* decomp: promote _sceFs_Rcv_Intr (900 B)\n\nThe semaphore release loop compared ret against the slot (bne operands\nreversed) and, with the slots read through a volatile table, the reversed\ncompare kept a separate sign-extension pseudo that took v0 from the\nsemaphore. Reading the table plainly lets combine fold the extension, and\nreleasing the slot through a volatile store keeps it ahead of the branch,\nout of the delay slot, as in retail.\n\n./verify-baseline.sh: PASS: reconstructed boot ELF matches retail","measures":{"fuzzy_match_percent":89.02808,"total_code":3546268,"matched_code":3113144,"matched_code_percent":87.78648,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3967,"matched_functions_percent":93.71604,"complete_code":3113144,"complete_code_percent":87.78648,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":400}},{"timestamp":"2026-10-14T05:59:20Z","commit_sha":"34fd269bf8814346997ab978334147dc4abce97b","commit_message":"overlay: exact wave 8, fourteen functions (#176)","measures":{"fuzzy_match_percent":89.02617,"total_code":3546268,"matched_code":3110044,"matched_code_percent":87.699066,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3964,"matched_functions_percent":93.64517,"complete_code":3110044,"complete_code_percent":87.699066,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":399}},{"timestamp":"2026-10-14T05:22:00Z","commit_sha":"297ffaf057b2b7206eddb2bb012f4a01611b5d83","commit_message":"decomp: promote cmd_sem_init and seven overlay functions (#175)\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve cmd_sem_init\n\n* decomp: improve music_transition\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve FUN_L00_002bcf98\n\n* decomp: improve FUN_L14_00301de8\n\n* decomp: improve FUN_L04_002ca420\n\n* decomp: improve FUN_L00_002c26c8\n\n* decomp: improve FUN_L01_0030df40\n\n* decomp: improve FUN_L05_00301f48\n\n* decomp: improve FUN_L00_002bffa8\n\n* decomp: improve FUN_L00_002c89e8\n\n* decomp: improve FUN_L12_00303370\n\n* decomp: improve FUN_L00_00261b48\n\n* decomp: improve FUN_L12_002e72c0\n\n* decomp: improve FUN_L07_0030f5f0\n\n* decomp: improve FUN_L08_002e3870\n\n* decomp: improve draw_debug_text\n\n* decomp: improve FUN_L00_002995d0\n\n* decomp: improve FUN_L00_002648e0\n\n* decomp: improve nanotech_upgrade_vendor\n\n* decomp: improve FUN_L07_00314150\n\n* decomp: improve FUN_L00_002c97e0\n\n* decomp: improve FUN_L01_00234358\n\n* decomp: improve FUN_L00_0020a9e8\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L05_00254358\n\n* decomp: improve FUN_L00_001fcca0\n\n* decomp: improve FUN_L04_002923b8\n\n* decomp: improve update_hero_held_items_and_orientation\n\n* decomp: improve FUN_L12_00308350\n\n* decomp: improve FUN_L11_00310cf8\n\n* decomp: improve scan_hero_input_sequences\n\n* decomp: improve FUN_L00_00262030\n\n* decomp: improve FUN_L00_0029ff58\n\n* decomp: improve FUN_L11_003192c8\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L10_002f5b58\n\n* decomp: improve FUN_L05_00262b58\n\n* decomp: improve FUN_L00_002464a8\n\n* decomp: improve FUN_L00_0020f160\n\n* decomp: improve FUN_L05_002f87a8\n\n* decomp: improve register_part_types\n\n* decomp: improve FUN_L15_001ff938\n\n* decomp: improve FUN_L00_0029ead8\n\n* decomp: improve FUN_L10_002e91b8\n\n* decomp: improve FUN_L15_002a3138\n\n* decomp: improve FUN_L00_002caf70\n\n* decomp: improve update_help_effect\n\n* decomp: improve FUN_L10_002e8ab0\n\n* decomp: improve FUN_L15_002e5958\n\n* decomp: improve FUN_L01_002b91c8\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve draw_quad_grid_with_dynamic_uvs\n\n* decomp: improve FUN_L08_002f44c0\n\n* decomp: improve FUN_L10_002da690\n\n* decomp: improve FUN_L00_002d9810\n\n* decomp: improve FUN_L02_002ea210\n\n* decomp: improve FUN_L14_00301fa8\n\n* decomp: improve FUN_L06_002feb40\n\n* decomp: improve FUN_L08_003024d8\n\n* decomp: improve FUN_L12_002bf140\n\n* decomp: improve FUN_L13_00306300\n\n* decomp: improve FUN_L06_00303160\n\n* decomp: improve FUN_L08_002dc9a8\n\n* decomp: improve FUN_L00_002ebe70\n\n* decomp: improve FUN_L05_00262f50\n\n* decomp: improve update_leg_rig_motion\n\n* decomp: improve update_motion_and_emit_effects\n\n* decomp: improve FUN_L00_0020dd20\n\n* decomp: improve FUN_L15_002aa280\n\n* decomp: improve FUN_L12_00304e00\n\n* decomp: improve FUN_L06_003049f8\n\n* decomp: improve FUN_L06_002fbfb0\n\n* decomp: improve FUN_L18_002e9768\n\n* decomp: improve FUN_L07_0030d4d8\n\n* decomp: improve update_path_camera\n\n* decomp: improve FUN_L08_002d23f0\n\n* decomp: improve FUN_L00_002a5040\n\n* decomp: improve FUN_L00_002484e0\n\n* decomp: improve set_pal_mode\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve set_pal_mode\n\n* decomp: improve update_level_gameplay_frame\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L06_002f5d78\n\n* decomp: improve FUN_L05_002d1688\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve FUN_L00_002382a0\n\n* decomp: improve update_moby_sequence\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve update_camera_record\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve FUN_L00_002cfcb8\n\n* decomp: improve FUN_L00_00260a88\n\n* decomp: improve FUN_L00_002dbf28\n\n* decomp: improve FUN_L01_002f5168\n\n* decomp: improve FUN_L00_002cd1f0\n\n* decomp: improve FUN_L00_002b77f0\n\n* decomp: improve FUN_L08_002f5e58\n\n* decomp: improve update_debug_menu\n\n* decomp: improve FUN_L13_002ba178\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve FUN_L00_002b49a8\n\n* decomp: improve FUN_L00_002ce358\n\n* decomp: improve FUN_L00_002ddf60\n\n* decomp: improve update_linked_moby_path_transition\n\n* decomp: improve FUN_L00_002d09b8\n\n* decomp: improve FUN_L12_002e9f68\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve FUN_L06_002f9a28\n\n* decomp: improve FUN_L01_002edca0\n\n* decomp: improve FUN_L00_002be650\n\n* decomp: improve FUN_L00_00257218\n\n* decomp: improve FUN_L06_002e8678\n\n* decomp: improve FUN_L13_00307e98\n\n* decomp: improve FUN_L00_00261b48\n\n* decomp: improve FUN_L01_00234358\n\n* decomp: improve FUN_L00_002d5de8\n\n* decomp: improve FUN_L08_002e2250\n\n* decomp: improve FUN_L00_002bcf98\n\n* decomp: improve FUN_L00_00257218\n\n* decomp: improve FUN_L05_00254358\n\n* decomp: improve FUN_L00_002cbcc0\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L00_00275aa0\n\n* decomp: improve FUN_L10_002e5be0\n\n* decomp: improve FUN_L08_002e2250\n\n* decomp: improve draw_debug_text\n\n* decomp: improve FUN_L00_00261b48\n\n* decomp: improve FUN_L00_002cbcc0\n\n* decomp: improve scan_hero_input_sequences\n\n* decomp: improve FUN_L00_002bcf98\n\n* decomp: improve FUN_L05_00254358\n\n* decomp: improve FUN_L00_002721f0\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L12_00308350\n\n* decomp: improve FUN_L02_00264e70\n\n* decomp: improve FUN_L00_0029ff58\n\n* decomp: improve spawn_troll_alert_particles\n\n* decomp: improve FUN_L00_002721f0\n\n* decomp: improve FUN_L00_00262030\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L05_00254058\n\n* decomp: improve FUN_L02_00264e70\n\n* decomp: improve FUN_L00_002721f0\n\n* decomp: improve draw_rope_strips\n\n* decomp: improve FUN_L18_002f9eb8\n\n* decomp: improve FUN_L06_00249738\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L11_003192c8\n\n* decomp: improve FUN_L10_002dcc58\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve FUN_L05_002f87a8\n\n* decomp: improve FUN_L05_00254058\n\n* decomp: improve FUN_L10_002f5b58\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L00_00275aa0\n\n* decomp: improve FUN_L00_0020f160\n\n* decomp: improve FUN_L14_002de670\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve FUN_L11_003192c8\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L06_002d8738\n\n* decomp: improve FUN_L10_002e91b8\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve FUN_L05_002f87a8\n\n* decomp: improve FUN_L07_0031d2e0\n\n* decomp: improve FUN_L08_002d3878\n\n* decomp: improve update_help_effect\n\n* decomp: improve FUN_L14_002dfd10\n\n* decomp: improve FUN_L01_002b91c8\n\n* decomp: improve FUN_L07_0030cf90\n\n* decomp: improve FUN_L10_002f5b58\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve FUN_L10_002da690\n\n* decomp: improve FUN_L08_002f44c0\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve FUN_L12_002bf140\n\n* decomp: improve draw_quad_grid_with_dynamic_uvs\n\n* decomp: improve FUN_L11_00310cf8\n\n* decomp: improve FUN_L00_00276368\n\n* decomp: improve FUN_L14_00301fa8\n\n* decomp: improve FUN_L08_003024d8\n\n* decomp: improve FUN_L06_002feb40\n\n* decomp: improve FUN_L01_002ef350\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve FUN_L10_002da690\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve FUN_L10_002e91b8\n\n* decomp: improve FUN_L14_00301fa8\n\n* decomp: improve FUN_L10_002dcc58\n\n* decomp: improve FUN_L06_002ff2c8\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve FUN_L00_002d9810\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve FUN_L06_00303160\n\n* decomp: improve FUN_L14_002b2928\n\n* decomp: improve update_motion_and_emit_effects\n\n* decomp: improve FUN_L08_002dc9a8\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve FUN_L07_00319040\n\n* decomp: improve FUN_L10_002da690\n\n* decomp: improve FUN_L14_003017f8\n\n* decomp: improve FUN_L10_002e91b8\n\n* decomp: improve FUN_L00_0020dd20\n\n* decomp: improve update_hero_held_items_and_orientation\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve FUN_L14_00301fa8\n\n* decomp: improve update_leg_rig_motion\n\n* decomp: improve FUN_L13_00306300\n\n* decomp: improve FUN_L10_002e91b8\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L14_00301fa8\n\n* decomp: improve FUN_L04_002923b8\n\n* decomp: improve FUN_L13_00306300\n\n* decomp: improve FUN_L00_0020f160\n\n* decomp: improve FUN_L06_002fbfb0\n\n* decomp: improve FUN_L00_00269d20\n\n* decomp: improve FUN_L14_00301fa8\n\n* decomp: improve FUN_L00_002a5040\n\n* decomp: improve FUN_L00_002772c0\n\n* decomp: improve FUN_L13_00306300\n\n* decomp: improve FUN_L00_002382a0\n\n* decomp: improve update_hero_held_items_and_orientation\n\n* decomp: improve update_path_camera\n\n* decomp: improve FUN_L10_002be858\n\n* decomp: improve FUN_L00_00260a88\n\n* decomp: improve FUN_L00_002d73e8\n\n* decomp: improve FUN_L06_002f5d78\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L00_002c89e8\n\n* decomp: improve FUN_L00_00276368\n\n* decomp: improve FUN_L14_003017f8\n\n* decomp: improve FUN_L00_00269d20\n\n* decomp: improve FUN_L10_002e91b8\n\n* decomp: improve update_hero_held_items_and_orientation\n\n* decomp: improve FUN_L00_0020f160\n\n* decomp: improve FUN_L00_00276368\n\n* decomp: improve FUN_L00_002382a0\n\n* decomp: improve update_motion_and_emit_effects\n\n* decomp: improve FUN_L06_002f5d78\n\n* overlay: reuse shared layouts and preserve canonical function names\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":88.46547,"total_code":3546268,"matched_code":3090160,"matched_code_percent":87.13837,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3950,"matched_functions_percent":93.31443,"complete_code":3090160,"complete_code_percent":87.13837,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":398}},{"timestamp":"2026-10-13T17:06:20Z","commit_sha":"59fa04961077fffa23445e9ca9ba83bbe0d342b0","commit_message":"overlay: exact wave 7, five functions (#174)\n\n* overlay: exact FUN_L04_0029ecf8, FUN_L01_00263a28 and FUN_L05_0031bf40\n\n* overlay: exact FUN_L01_002b8f98\n\n* overlay: exact FUN_L08_002d55c8","measures":{"fuzzy_match_percent":88.23086,"total_code":3546268,"matched_code":3081692,"matched_code_percent":86.89958,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3942,"matched_functions_percent":93.12544,"complete_code":3081692,"complete_code_percent":86.89958,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":397}},{"timestamp":"2026-10-13T16:42:09Z","commit_sha":"5c2acf3b2e2086e1d525faacf535e9ef55fe9aa8","commit_message":"overlay: gaspar mountable turret update (3492 B) (#173)\n\nFUN_L09_00304c80, the last pending function of l09. The sound-probe\nglobal D_0013E5BC is declared as an array (retail keeps its store\nahead of the moby loads), and the case-0 zero stores follow the\norder that frees the vars register last.","measures":{"fuzzy_match_percent":88.060425,"total_code":3546268,"matched_code":3075648,"matched_code_percent":86.72915,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3937,"matched_functions_percent":93.007324,"complete_code":3075648,"complete_code_percent":86.72915,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":394}},{"timestamp":"2026-10-13T16:41:32Z","commit_sha":"f745654d40d09b8e739a5f86a5b874431f601d91","commit_message":"overlay: three Veldin 2 functions (#172)\n\n* overlay: veldin 2 sinking platform update (1104 B)\n\nFUN_L18_002d82c0, from the rac1-decomp draft (ported from rac1-decomp).\nCase 3 writes its scaled rate to a new variable and case 5 uses its own\nratio variable with each gravity arm spelled out in full, which cross-jumps\ninto retail's shared tail.\n\n* overlay: veldin 2 glow trail draw callback (816 B)\n\nFUN_L18_002f0390 in exact C. The moby search is a goto loop (no loop\nnotes, so the *p reload stays in the loop as retail), and the draw loop\nuses its own counter so it gets a separate register from the build loop.\n\n* overlay: veldin 2 sentry update (988 B)\n\nFUN_L18_002fc100 in exact C. D_L18_0015F5C4 and D_L18_0015F5CC stay\nplain externs: retail reads them only in branch delay slots, where the\nassembler (nomacro) goes through $gp anyway, so no sda declaration is\nneeded and the lui accesses in the rest of the file stay as they are.","measures":{"fuzzy_match_percent":87.96195,"total_code":3546268,"matched_code":3072156,"matched_code_percent":86.63068,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3936,"matched_functions_percent":92.9837,"complete_code":3072156,"complete_code_percent":86.63068,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":393}},{"timestamp":"2026-10-13T14:37:04Z","commit_sha":"e934c0aa83814274b9923b236e0847b72ef03189","commit_message":"overlay: exact wave 6 (10 more overlay functions in exact c) (#171)\n\n* overlay: decompile the pose packer FUN_L00_002092c8\n\npack_pose writes every listed scratchpad joint rotation, identity padding,\nthe scales that are not 1.0 and the translations that differ from the\nmodel's bind pose as packed s16 vectors after a PackedPose header.\n\n* overlay: decompile FUN_L00_002599e8 (returns the callee's value)\n\n* overlay: port FUN_L07_002f5ba0 from rac1-decomp\n\n* overlay: port FUN_L00_002c6158 from rac1-decomp\n\n* overlay: port FUN_L00_002b87e0 from rac1-decomp\n\n* overlay: port FUN_L00_002b03a0 from rac1-decomp\n\n* overlay: port FUN_L11_0030b358 from rac1-decomp\n\n* overlay: port FUN_L00_00245c28 from rac1-decomp\n\n* overlay: port FUN_L13_002b50d8 from rac1-decomp\n\n* overlay: name ported aliases after their us labels\n\n* overlay: match FUN_L06_0030bfa8\n\n* overlay: restore the 00245c28 unit tail dropped by the port","measures":{"fuzzy_match_percent":87.87995,"total_code":3546268,"matched_code":3069248,"matched_code_percent":86.548676,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3933,"matched_functions_percent":92.91283,"complete_code":3069248,"complete_code_percent":86.548676,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":392}},{"timestamp":"2026-10-13T11:53:09Z","commit_sha":"794c3305a289d6fe38647f0e46121b055d221461","commit_message":"decomp: batch 14 resident and overlay C improvements (#170)\n\n* decomp: improve draw_quad_grid_with_dynamic_uvs\n\n* decomp: improve FUN_L01_002b91c8\n\n* decomp: improve FUN_L08_002d3878\n\n* decomp: improve FUN_L07_002f5ba0\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve FUN_L15_002e5958\n\n* decomp: improve FUN_L10_002da690\n\n* decomp: improve FUN_L10_002e8ab0\n\n* decomp: improve FUN_L02_002ea210\n\n* decomp: improve FUN_L14_00301fa8\n\n* decomp: improve draw_hud_stars\n\n* decomp: improve FUN_L00_00276368\n\n* decomp: improve FUN_L14_002b2928\n\n* decomp: improve FUN_L00_002d9810\n\n* decomp: improve FUN_L06_002feb40\n\n* decomp: improve FUN_L00_002be078\n\n* decomp: improve FUN_L04_0029ecf8\n\n* decomp: improve FUN_L15_002d0fa8\n\n* decomp: improve FUN_L00_0023db30\n\n* decomp: improve FUN_L08_003024d8\n\n* decomp: improve FUN_L08_002dc9a8\n\n* decomp: improve FUN_L14_003017f8\n\n* decomp: improve FUN_L11_003094f8\n\n* decomp: improve scan_hero_input_sequences\n\n* decomp: improve FUN_L00_0020dd20\n\n* decomp: improve FUN_L00_002ebe70\n\n* decomp: improve FUN_L13_00306300\n\n* decomp: improve FUN_L06_00303160\n\n* decomp: improve FUN_L06_002fbfb0\n\n* decomp: improve FUN_L00_002a3ec8\n\n* decomp: improve update_path_flyer_state\n\n* decomp: improve FUN_L15_0029a570\n\n* decomp: improve update_motion_and_emit_effects\n\n* decomp: improve FUN_L12_00304e00\n\n* decomp: improve FUN_L15_002aa280\n\n* decomp: improve FUN_L06_003049f8\n\n* decomp: improve FUN_L00_002772c0\n\n* decomp: improve FUN_L18_002e9768\n\n* decomp: improve FUN_L06_002f5d78\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L00_002484e0\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L00_002a5040\n\n* decomp: improve FUN_L08_002d23f0\n\n* decomp: improve FUN_L01_002eec68\n\n* decomp: improve FUN_L00_002d73e8\n\n* decomp: improve FUN_L10_002be858\n\n* decomp: improve update_camera_record\n\n* decomp: improve FUN_L00_0025c698\n\n* decomp: improve FUN_L00_00245c28\n\n* decomp: improve FUN_L00_002382a0\n\n* decomp: improve FUN_L00_00260a88\n\n* decomp: improve FUN_L03_002c4718\n\n* decomp: improve FUN_L05_002d1688\n\n* decomp: improve update_moby_state_and_emit_effects\n\n* decomp: improve FUN_L00_002c1ad0\n\n* decomp: improve FUN_L05_0031bf40\n\n* decomp: improve FUN_L00_002dbf28\n\n* decomp: improve FUN_L00_002cfcb8\n\n* decomp: improve FUN_L00_002b77f0\n\n* decomp: improve update_moby_sequence\n\n* decomp: improve FUN_L13_002ba178\n\n* decomp: improve FUN_L02_002d93e8\n\n* decomp: improve FUN_L01_002f5168\n\n* decomp: improve FUN_L00_002ddf60\n\n* decomp: improve FUN_L00_002d09b8\n\n* decomp: improve FUN_L00_002c6158\n\n* decomp: improve update_debug_menu\n\n* decomp: improve FUN_L08_002f5e58\n\n* decomp: improve FUN_L01_002edca0\n\n* decomp: improve FUN_L00_002c4380\n\n* decomp: improve FUN_L00_002cd1f0\n\n* decomp: improve FUN_L00_002b49a8\n\n* decomp: improve FUN_L00_002b03a0\n\n* decomp: improve FUN_L00_002d3a10\n\n* decomp: improve FUN_L00_002ce358\n\n* decomp: improve FUN_L00_002bc3b0\n\n* decomp: improve update_hero_item_slots\n\n* decomp: improve FUN_L14_002e0170\n\n* decomp: improve FUN_L00_00257218\n\n* decomp: improve update_hero_item_slots\n\n* decomp: improve FUN_L00_00262030\n\n* decomp: improve FUN_L00_0023a2d0\n\n* decomp: improve update_route_following_moby\n\n* decomp: improve FUN_L02_00264e70\n\n* decomp: improve update_hero_item_slots\n\n* decomp: improve FUN_L05_0030c220\n\n* decomp: improve FUN_L00_0023a2d0\n\n* decomp: improve FUN_L05_00266320\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L00_002464a8\n\n* decomp: improve FUN_L14_002de670\n\n* decomp: improve FUN_L00_00262030\n\n* decomp: improve FUN_L05_0030c220\n\n* decomp: improve FUN_L00_002d2670\n\n* decomp: improve FUN_L05_00262b58\n\n* decomp: improve FUN_L00_0023a2d0\n\n* decomp: improve FUN_L00_002acfd8\n\n* decomp: improve FUN_L07_0031d2e0\n\n* decomp: improve FUN_L00_002d2670\n\n* decomp: improve FUN_L00_0023db30\n\n* decomp: improve FUN_L00_00261b48\n\n* decomp: improve FUN_L00_002acfd8\n\n* decomp: improve build_packet_and_draw_scaled_entries\n\n* decomp: improve FUN_L05_0030c220\n\n* decomp: improve FUN_L05_00262b58\n\n* decomp: improve FUN_L15_002e5958\n\n* decomp: improve FUN_L00_002464a8\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L00_002d2670\n\n* decomp: improve FUN_L08_002e8210\n\n* decomp: improve FUN_L10_002e8ab0\n\n* decomp: improve draw_hud_stars\n\n* decomp: improve FUN_L00_002acfd8\n\n* decomp: improve FUN_L08_002f44c0\n\n* decomp: improve FUN_L06_002feb40\n\n* decomp: improve build_packet_and_draw_scaled_entries\n\n* decomp: improve FUN_L04_0029ecf8\n\n* decomp: improve FUN_L05_00262b58\n\n* decomp: improve FUN_L05_0030c220\n\n* decomp: improve FUN_L15_002e5958\n\n* decomp: improve FUN_L00_002d2670\n\n* decomp: improve FUN_L14_003017f8\n\n* decomp: improve FUN_L00_002464a8\n\n* decomp: improve FUN_L05_00262b58\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L06_002ff2c8\n\n* decomp: improve FUN_L06_003049f8\n\n* decomp: improve update_path_flyer_state\n\n* decomp: improve FUN_L04_0029ecf8\n\n* decomp: improve build_packet_and_draw_scaled_entries\n\n* decomp: improve FUN_L00_002d2670\n\n* decomp: improve FUN_L05_00262b58\n\n* decomp: improve FUN_L15_0029a570\n\n* decomp: improve draw_hud_stars\n\n* decomp: improve FUN_L05_002f87a8\n\n* decomp: improve FUN_L06_002ff2c8\n\n* decomp: improve FUN_L04_0029ecf8\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve build_packet_and_draw_scaled_entries\n\n* decomp: improve update_path_flyer_state\n\n* decomp: improve FUN_L15_002e5958\n\n* decomp: improve FUN_L14_003017f8\n\n* decomp: improve FUN_L15_002bddb0\n\n* decomp: improve FUN_L05_00262b58\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L12_00304e00\n\n* decomp: improve FUN_L04_0029ecf8\n\n* decomp: improve FUN_L00_002d2158\n\n* decomp: improve FUN_L00_002772c0\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L18_002e9768\n\n* decomp: improve FUN_L05_002f87a8\n\n* decomp: improve FUN_L05_00262f50\n\n* decomp: improve FUN_L00_002a5040\n\n* decomp: improve FUN_L15_002e5958\n\n* decomp: improve FUN_L00_002484e0\n\n* decomp: improve FUN_L12_00306828\n\n* decomp: improve FUN_L00_002d2158\n\n* decomp: improve FUN_L05_002f87a8\n\n* decomp: improve FUN_L05_00262f50\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L00_002484e0\n\n* decomp: improve FUN_L00_002d2158\n\n* decomp: improve FUN_L00_00260a88\n\n* decomp: improve update_camera_record\n\n* decomp: improve FUN_L05_00262f50\n\n* decomp: improve FUN_L07_0030b000\n\n* decomp: improve FUN_L00_0025c698\n\n* decomp: improve update_spawned_moby\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L00_002d2158\n\n* decomp: improve update_moby_state_and_emit_effects\n\n* decomp: improve FUN_L05_0031bf40\n\n* decomp: improve update_spawned_moby\n\n* decomp: improve FUN_L00_0025c698\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L00_002d2158\n\n* decomp: improve update_camera_record\n\n* decomp: improve FUN_L05_0031bf40\n\n* decomp: improve FUN_L00_00260a88\n\n* decomp: improve FUN_L00_0025c698\n\n* decomp: improve FUN_L00_002c4380\n\n* decomp: improve update_moby_state_and_emit_effects\n\n* decomp: improve FUN_L13_002ba178\n\n* decomp: improve FUN_L01_002edca0\n\n* decomp: improve FUN_L07_0030d4d8\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L05_0031bf40\n\n* decomp: improve FUN_L01_002ef350\n\n* decomp: improve update_debug_menu\n\n* decomp: improve FUN_L05_0031bf40\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve update_debug_menu\n\n* decomp: improve update_debug_menu\n\n* decomp: improve scan_hero_input_sequences\n\n* decomp: improve FUN_L00_00237840\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L00_002be650\n\n* decomp: improve FUN_L08_002de528\n\n* decomp: improve FUN_L00_00237840\n\n* decomp: improve update_hero_held_items_and_orientation\n\n* decomp: improve FUN_L12_00308350\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve FUN_L11_00310cf8\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve create_moby_with_particles\n\n* decomp: improve FUN_L18_002ea1f8\n\n* decomp: improve find_nearest_path_point\n\n* decomp: improve FUN_L00_002be650\n\n* decomp: improve FUN_L10_002dcc58\n\n* decomp: improve FUN_L12_00306828\n\n* decomp: improve FUN_L11_00310cf8\n\n* decomp: improve FUN_L14_002dfd10\n\n* decomp: improve FUN_L06_002d8738\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve create_moby_with_particles\n\n* decomp: improve find_nearest_path_point\n\n* decomp: improve FUN_L18_002ea1f8\n\n* decomp: improve FUN_L10_002dcc58\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve create_moby_with_particles\n\n* decomp: improve FUN_L12_00306828\n\n* decomp: improve find_nearest_path_point\n\n* decomp: improve FUN_L06_002d8738\n\n* decomp: improve FUN_L18_002ea1f8\n\n* decomp: improve FUN_L10_002dcc58\n\n* decomp: improve FUN_L00_0029ead8\n\n* decomp: improve FUN_L05_002d7920\n\n* decomp: improve FUN_L00_0020f160\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve FUN_L15_002a3138\n\n* decomp: improve FUN_L12_00303370\n\n* decomp: improve FUN_L06_002d8738\n\n* decomp: improve FUN_L01_002b91c8\n\n* decomp: improve FUN_L10_002dcc58\n\n* decomp: improve FUN_L18_002ea1f8\n\n* decomp: improve FUN_L08_002d3878\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve FUN_L00_0029ead8\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve FUN_L07_002f5ba0\n\n* decomp: improve FUN_L12_00303370\n\n* decomp: improve FUN_L15_002bddb0\n\n* decomp: improve FUN_L06_002d8738\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve update_help_effect\n\n* decomp: adopt upstream Moby field names\n\n* decomp: reconcile upstream overlay declarations and field names\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":87.07347,"total_code":3546268,"matched_code":3040648,"matched_code_percent":85.742195,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3923,"matched_functions_percent":92.67659,"complete_code":3040648,"complete_code_percent":85.742195,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":392}},{"timestamp":"2026-10-13T08:50:10Z","commit_sha":"19c960daa516034ca859ea0426f2685959b82d5a","commit_message":"overlay: exact wave 5 (3 more overlay functions in exact c) (#169)\n\n* overlay: one shared function exact on the sn route\n\nThe unit 002df730.c moves to OVERLAY_SN_UNITS: its NON_MATCHING draft of\nFUN_L00_002df808 (396 B, 19 levels) is exact there. FUN_L00_002e88c8 needed\ndead if-blocks on the game compiler; on SN it is plain C returning the\ncallee's float.\n\n* overlay: suck cannon update exact in c\n\nPort the Suck Cannon state update (FUN_L00_002da790, 4280 bytes, every level) from the migrated source. The two vector copies go through the 128-bit field so they stay one lq/sq pair. Its hero, item and voice fields are named by use.\n\n* overlay: devastator update exact in c\n\nPort the Devastator state update (FUN_L00_002b2100, 3928 bytes, every level) from the migrated source. hero.h gains the slot 6 lock target at 0x48, which the weapons read while the lock is on.\n\n* overlay: name the aim probe and offset vectors by use","measures":{"fuzzy_match_percent":86.72185,"total_code":3546268,"matched_code":3026476,"matched_code_percent":85.34256,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3909,"matched_functions_percent":92.345856,"complete_code":3026476,"complete_code_percent":85.34256,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":389}},{"timestamp":"2026-10-13T06:59:06Z","commit_sha":"ddb25b08525330d515ceaec15498f9dac7baea86","commit_message":"overlay: exact wave 4 (3 more overlay functions in exact C) (#168)","measures":{"fuzzy_match_percent":86.47923,"total_code":3546268,"matched_code":3017872,"matched_code_percent":85.099945,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3906,"matched_functions_percent":92.27498,"complete_code":3017872,"complete_code_percent":85.099945,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":389}},{"timestamp":"2026-10-13T05:28:35Z","commit_sha":"6b408d7961c0acc94396978f9234ac0467b3b28b","commit_message":"overlay: exact wave 3 (67 more overlay functions in exact c) (#167)","measures":{"fuzzy_match_percent":86.38685,"total_code":3546268,"matched_code":3014596,"matched_code_percent":85.00756,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3903,"matched_functions_percent":92.20411,"complete_code":3014596,"complete_code_percent":85.00756,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":389}},{"timestamp":"2026-10-12T18:25:53Z","commit_sha":"0ee0bc4d001abe0f228387c8b5fa33bb43607015","commit_message":"overlay: 11 more level functions in exact C (#166)\n\n* decomp: 4 more overlay functions in exact C\n\n* decomp: one more level 13 function in exact C\n\n* decomp: one more level 8 function in exact C\n\n* decomp: one more level 5 function in exact C\n\n* decomp: one more level 1 function in exact C\n\n* decomp: one more shared level function in exact C\n\n* decomp: one more level 2 function in exact C\n\n* decomp: one more shared level function in exact C\n\n* decomp: two more level 5 functions in exact C\n\n* decomp: name locals and helpers in the new exact functions","measures":{"fuzzy_match_percent":83.57116,"total_code":3546268,"matched_code":2914744,"matched_code_percent":82.19187,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3836,"matched_functions_percent":90.62131,"complete_code":2914744,"complete_code_percent":82.19187,"complete_data":0,"complete_data_percent":0,"total_units":512,"complete_units":376}},{"timestamp":"2026-10-12T18:16:09Z","commit_sha":"78106fe03581a3c3dd84c6e59d59613e23abda89","commit_message":"decomp: recover names for functions, globals and struct fields (#165)\n\n* decomp: name boot functions and globals from RC1 and ReRAC\n\nFunction names for four unnamed executable functions (sceCdDiskReady,\nactuator_calc_power, point_is_clockwise, patch_shrub_gifs); three more\nReRAC suggestions are recorded as needs_review in the catalog.\n\n288 globals the C reaches by their D_ address get the names RC1 or ReRAC\ngive them, bound to the D_ symbol with an asm label. Names where the two\nprojects disagree, or that would shadow an existing identifier, are left\nout.\n\n* overlay: name 23 shared level functions from ReRAC\n\nThe collision, hero movement, random, particle, help and sky-shell helpers\nReRAC names (verified or inferred) take that name at their definition and\nat every plain FUN_L call site. Where our sources already use a name for\nthe same function in five or more files (set_hero_animation,\nrandom_int_between, random_vector, queue_dialogue_message,\ncollect_mobies_in_sphere) that name is kept. Files that bind a function\nunder a local alias keep it, so no prototype changes.\n\n* decomp: name Moby, MobyClass and Hero fields from ReRAC and RC1\n\n33 unkXX fields get the names ReRAC documents for the same offsets (RC1\nagrees where it names them): the moby's class slot, alpha, update and\ndraw distances, occlusion bits, animation time/speed/flags, shadow range,\nglow colour, collision data and disable bits, hit slot, mission byte,\nparent, command byte and matrix rows; the class header's collision data,\nretarget table, sound definitions and type; the hero's platform delta,\ndisplacement, capsule top, gravity direction, ground pitch, grounded\nframes and stick vector. Field comments carry the evidence; layout\nchecks follow.\n\n* config: record ReRAC's suggested names for seven boot functions\n\nThey stay needs_review in the catalog; no source changes.\n\n* overlay: record ReRAC's level function names as name evidence\n\nlevel-01 (and one level-05) entries carry ReRAC's name and confidence,\nso the 396 suggested names are kept for later review; only verified and\ninferred ones are applied in src/overlays.\n\n* docs: credit ReRAC in the README\n\n* docs: list ReRAC with the other reference projects","measures":{"fuzzy_match_percent":83.319626,"total_code":3546268,"matched_code":2905824,"matched_code_percent":81.94034,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3825,"matched_functions_percent":90.36144,"complete_code":2905824,"complete_code_percent":81.94034,"complete_data":0,"complete_data_percent":0,"total_units":512,"complete_units":374}},{"timestamp":"2026-10-12T17:35:06Z","commit_sha":"c886f84162b354a8d32ca64448e5e39943c60aa2","commit_message":"decomp: decompilerizer batch 13 (#164)\n\n* decomp: improve select_world_object_resource_tables\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve update_mode_freeze\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve sceDbcCreateSocket\n\n* decomp: improve draw_level_selection_map\n\n* decomp: improve render_vendor_capture_pass_sequence\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve _printf\n\n* decomp: improve sceGsSetDefLoadImage\n\n* decomp: improve sceFsInit\n\n* decomp: improve project_graphics_bounds\n\n* decomp: improve decode_compressed_occlusion_map\n\n* decomp: improve draw_map_markers\n\n* decomp: improve project_graphics_bounds\n\n* decomp: improve project_graphics_bounds_float\n\n* decomp: improve render_vendor_buy_label_pass\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve vi_buf_restart_dma\n\n* decomp: improve update_streamed_moby_animation\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve sceCdInit\n\n* decomp: improve upload_mip_texture\n\n* decomp: improve nanotech_upgrade_vendor\n\n* decomp: improve FUN_L14_002e0170\n\n* decomp: improve FUN_L13_002e97e0\n\n* decomp: improve FUN_L01_00276fe8\n\n* decomp: improve draw_debug_text\n\n* decomp: improve FUN_L00_0029ad08\n\n* decomp: improve FUN_L00_002092c8\n\n* decomp: improve FUN_L00_00257218\n\n* decomp: improve FUN_L01_00263a28\n\n* decomp: improve FUN_L01_0028bb90\n\n* decomp: improve FUN_L00_002648e0\n\n* decomp: improve FUN_L00_002ebbd8\n\n* decomp: improve FUN_L00_0026b500\n\n* decomp: improve FUN_L08_002e2250\n\n* decomp: improve FUN_L01_00234358\n\n* decomp: improve initialize_level_graphics_frame_effect_state\n\n* decomp: improve FUN_L00_00261d78\n\n* decomp: improve FUN_L00_00237840\n\n* decomp: improve FUN_L05_00254358\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L08_002e9758\n\n* decomp: improve FUN_L04_002923b8\n\n* decomp: improve FUN_L00_00275aa0\n\n* decomp: improve FUN_L00_0026b230\n\n* decomp: improve FUN_L06_002fd1a0\n\n* decomp: improve FUN_L10_002e5be0\n\n* decomp: improve FUN_L12_00302c58\n\n* decomp: improve scan_hero_input_sequences\n\n* decomp: improve FUN_L00_001fcca0\n\n* decomp: improve FUN_L00_00299c48\n\n* decomp: improve FUN_L14_002df138\n\n* decomp: improve FUN_L05_00254058\n\n* decomp: improve FUN_L08_002de528\n\n* decomp: improve restore_or_clear_level_state\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve FUN_L01_002ef770\n\n* decomp: improve FUN_L06_002e9b60\n\n* decomp: improve FUN_L18_002f0390\n\n* decomp: improve FUN_L15_002c4f88\n\n* decomp: improve FUN_L13_002ed158\n\n* decomp: improve FUN_L11_00310cf8\n\n* decomp: improve update_linked_moby_scene_trigger\n\n* decomp: improve FUN_L00_00262030\n\n* decomp: improve FUN_L00_002b6bc8\n\n* decomp: improve FUN_L00_00214fe8\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve FUN_L00_0029ff58\n\n* decomp: improve FUN_L00_002056a8\n\n* decomp: improve FUN_L01_0030c9a8\n\n* decomp: improve update_route_following_moby\n\n* decomp: improve FUN_L05_0024bdc0\n\n* decomp: improve create_moby_with_particles\n\n* decomp: improve FUN_L00_0023a2d0\n\n* decomp: improve draw_rope_strips\n\n* decomp: improve spawn_troll_alert_particles\n\n* decomp: improve FUN_L15_002edbe0\n\n* decomp: improve FUN_L06_00249738\n\n* decomp: improve FUN_L00_002721f0\n\n* decomp: improve FUN_L18_002f9eb8\n\n* decomp: improve FUN_L05_0030c220\n\n* decomp: improve FUN_L00_00228c18\n\n* decomp: improve FUN_L00_002e7618\n\n* decomp: improve FUN_L18_002ea1f8\n\n* decomp: improve FUN_L13_0030cdb8\n\n* decomp: improve find_nearest_path_point\n\n* decomp: improve FUN_L10_002dcc58\n\n* decomp: improve initialize_linked_motion_paths\n\n* decomp: improve FUN_L11_003192c8\n\n* decomp: improve FUN_L06_002ff2c8\n\n* decomp: improve FUN_L10_002f5b58\n\n* decomp: improve FUN_L05_002f87a8\n\n* decomp: improve FUN_L10_002da2c8\n\n* decomp: improve FUN_L05_002d7920\n\n* decomp: improve FUN_L00_0023fa00\n\n* decomp: improve FUN_L00_002d2670\n\n* decomp: improve FUN_L15_001ff938\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L01_0030b618\n\n* decomp: improve FUN_L08_002e5188\n\n* decomp: improve FUN_L00_0020f160\n\n* decomp: improve FUN_L00_002464a8\n\n* decomp: improve FUN_L13_002c3fc0\n\n* decomp: improve FUN_L00_0029ead8\n\n* decomp: improve FUN_L06_002d8738\n\n* decomp: improve FUN_L18_002d82c0\n\n* decomp: improve FUN_L10_002e91b8\n\n* decomp: improve FUN_L00_002acfd8\n\n* decomp: improve FUN_L15_002d0fa8\n\n* decomp: improve FUN_L00_0025ff38\n\n* decomp: improve update_linked_moby_hitbox\n\n* decomp: improve FUN_L00_002bc3b0\n\n* decomp: improve FUN_L07_0031d2e0\n\n* decomp: improve FUN_L15_002a3138\n\n* decomp: improve FUN_L00_002caf70\n\n* decomp: improve FUN_L14_002dfd10\n\n* decomp: improve FUN_L15_0029aff0\n\n* decomp: improve build_packet_and_draw_scaled_entries\n\n* decomp: improve FUN_L10_002d7b80\n\n* decomp: improve draw_quad_grid_with_dynamic_uvs\n\n* decomp: improve FUN_L07_00310df0\n\n* decomp: improve FUN_L07_00313420\n\n* decomp: improve FUN_L08_002d3878\n\n* decomp: improve FUN_L05_00253b48\n\n* decomp: improve _sceFs_Rcv_Intr\n\n* decomp: improve FUN_L15_002e5958\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve set_pal_mode\n\n* decomp: improve _getAllRefs\n\n* decomp: improve font_print_window\n\n* decomp: improve render_vendor_capture_pass_sequence\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve sceCdInit\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve initialize_render_archive_transfer\n\n* decomp: improve FUN_L07_0029b8d8\n\n* decomp: improve FUN_L12_00306828\n\n* decomp: improve FUN_L14_00301de8\n\n* decomp: improve FUN_L01_0030bfa8\n\n* decomp: improve FUN_L00_00261968\n\n* decomp: improve FUN_L04_002d1418\n\n* decomp: improve FUN_L00_00236268\n\n* decomp: improve FUN_L07_00311eb8\n\n* decomp: improve FUN_L00_002995d0\n\n* decomp: improve FUN_L00_002db8f8\n\n* decomp: improve FUN_L00_0023d198\n\n* decomp: improve FUN_L01_002ef350\n\n* decomp: improve FUN_L07_0031a9e8\n\n* decomp: improve sceCdInit\n\n* decomp: improve FUN_L07_002f5ba0\n\n* decomp: improve FUN_L00_0023db30\n\n* decomp: improve draw_hud_stars\n\n* decomp: improve FUN_L00_002d2158\n\n* decomp: improve FUN_L07_0031aee0\n\n* decomp: improve FUN_L08_002f44c0\n\n* decomp: improve FUN_L08_002e8210\n\n* decomp: improve FUN_L10_002da690\n\n* decomp: improve FUN_L10_002e8ab0\n\n* decomp: improve FUN_L13_002e4448\n\n* decomp: improve FUN_L13_0030b628\n\n* decomp: improve FUN_L07_0030b000\n\n* decomp: improve FUN_L12_002bf140\n\n* decomp: improve FUN_L14_002b2928\n\n* decomp: improve FUN_L14_00301fa8\n\n* decomp: improve FUN_L04_0029ecf8\n\n* decomp: improve FUN_L06_002feb40\n\n* decomp: improve FUN_L00_002d9810\n\n* decomp: improve FUN_L11_003094f8\n\n* decomp: improve FUN_L02_002ea210\n\n* decomp: improve FUN_L06_002ffcb0\n\n* decomp: improve FUN_L08_002dc9a8\n\n* decomp: improve FUN_L04_002d7e90\n\n* decomp: guard pending resident object updates for plain C recovery\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve sceGsSetDefDispEnv\n\n* fix: remove conflicting stale overlay helper declarations\n\n* decomp: improve FUN_L00_002484e0\n\n* decomp: improve generate_random_points_from_shape_entries\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L18_002e9768\n\n* decomp: improve FUN_L00_002d73e8\n\n* decomp: improve FUN_L08_003024d8\n\n* decomp: improve FUN_L15_002a7880\n\n* decomp: improve FUN_L13_00305a58\n\n* decomp: improve update_vendor_slot_moby\n\n* decomp: improve FUN_L08_00307540\n\n* decomp: improve FUN_L00_00269d20\n\n* decomp: improve predict_throw_landing\n\n* decomp: improve FUN_L00_002a5040\n\n* decomp: improve FUN_L05_00305178\n\n* decomp: improve FUN_L18_002fc100\n\n* decomp: improve update_hero_ledge_probe\n\n* decomp: improve FUN_L06_003049f8\n\n* decomp: improve FUN_L07_0030d4d8\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":83.319626,"total_code":3546268,"matched_code":2905824,"matched_code_percent":81.94034,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3825,"matched_functions_percent":90.36144,"complete_code":2905824,"complete_code_percent":81.94034,"complete_data":0,"complete_data_percent":0,"total_units":512,"complete_units":374}},{"timestamp":"2026-10-12T15:17:33Z","commit_sha":"4c0023262922cee5f8f28f6f99d6b6d95fd0a683","commit_message":"decomp: 48 more overlay functions in exact C (#163)\n\n* fix: skip NON_MATCHING drafts when hoisting SN small-data externs\n\nThe SN assembler step read every __attribute__((sda)) declaration in the\nsource text, including the ones inside NON_MATCHING #else drafts that the\ncompiler never sees. A draft's sda declaration then turned a live lui\naccess into a $gp one and made a correct function 4 bytes short.\nmake overlays and the boot ELF gate both PASS.\n\n* overlay: port six level functions from rac1-decomp\n\nFUN_L00_00258830, FUN_L04_001f30e0, FUN_L09_003082d8, FUN_L10_002df270,\nFUN_L12_002e3ed8 and FUN_L12_00302f30 (10,820 bytes, 24 level copies).\nFixes on top of the port: re-paired data symbols, the flag table base\nwithout an offset, a .sdata alias where the unit reaches a symbol through\n$gp, and the path count read once into a local. Two NON_MATCHING drafts\nare replaced by the exact C. make overlays: PASS (2615 functions).\n\n* overlay: port FUN_L00_00238f88 from rac1-decomp\n\nData re-paired from the listing: the ring radius, aspect and offset, the\ntable and its index, and the two text colours.\n\n* overlay: port FUN_L10_002e85b8 from rac1-decomp\n\nThe PAL address arithmetic is rebased on the US symbols the listing uses\n(hero, save block, story flags), and the moby list and its head re-paired.\n\n* overlay: port FUN_L11_0030ee00 from rac1-decomp\n\n* overlay: port FUN_L12_00304218 from rac1-decomp\n\n* overlay: port FUN_L00_002bc7e8 from rac1-decomp\n\nThe hero's rotation rows at 0x640 get a field (basis), used by the port\nas the transform_vector_by_basis argument.\n\n* overlay: decompile FUN_L12_002e1be0\n\n* overlay: decompile FUN_L09_002c6230 and FUN_L12_003028c8\n\n* overlay: decompile FUN_L00_002d89f0\n\n* overlay: decompile FUN_L00_002bf9f0\n\n* overlay: decompile FUN_L09_003091b0 and FUN_L09_002f86a0\n\n* overlay: decompile FUN_L08_002d5950\n\n* overlay: decompile FUN_L06_002f91e8\n\n* overlay: decompile FUN_L08_002deee0\n\n* overlay: decompile FUN_L08_002d2af0\n\n* overlay: decompile FUN_L08_002e0328\n\n* overlay: decompile FUN_L09_002e27d8 (unit builds with SN)\n\n* overlay: decompile FUN_L13_002eb098\n\n* overlay: decompile FUN_L03_002cca00\n\n* overlay: decompile FUN_L08_00301158\n\n* overlay: call ported helpers by their header names\n\n* overlay: decompile FUN_L05_002d7140\n\n* overlay: decompile FUN_L09_0021e560\n\n* overlay: decompile FUN_L02_002a40f0\n\n* overlay: decompile FUN_L06_002f55a0\n\n* overlay: decompile FUN_L08_002d4ca0\n\n* overlay: decompile FUN_L04_002e4418\n\n* overlay: decompile FUN_L00_0020bed0\n\n* overlay: decompile FUN_L00_002e2250 and FUN_L15_002d7bb0\n\n* overlay: decompile FUN_L08_002dd3c0\n\n* overlay: decompile FUN_L05_00307910\n\n* overlay: decompile FUN_L00_002dc9f0\n\n* overlay: decompile FUN_L01_00315358\n\n* overlay: decompile FUN_L12_00303540\n\n* overlay: decompile FUN_L00_002df9a0\n\n* overlay: decompile FUN_L02_002d8ad0\n\n* overlay: decompile FUN_L05_00251be8\n\n* overlay: decompile FUN_L00_002bd0a0\n\n* overlay: decompile FUN_L03_002d47c0\n\n* overlay: decompile FUN_L01_002f6a30\n\n* overlay: decompile FUN_L05_00329ce8\n\n* decomp: use the shared names for vector helpers in this batch\n\n* decomp: restore confirmed names from the earlier drafts\n\n* decomp: name locals, params and fields by use in this batch","measures":{"fuzzy_match_percent":82.95472,"total_code":3546268,"matched_code":2892136,"matched_code_percent":81.55435,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3809,"matched_functions_percent":89.98346,"complete_code":2892136,"complete_code_percent":81.55435,"complete_data":0,"complete_data_percent":0,"total_units":512,"complete_units":370}},{"timestamp":"2026-10-12T09:57:10Z","commit_sha":"addaa2f55820cba0d5ac1732cdce6056def0b141","commit_message":"overlay: migrate the debug menu and nine more functions to C (#162)\n\n* decomp: name hero fields that were padding (0x238, 0x244, 0x934, 0x1024 group, 0x221C)\n\n* decomp: match update_visible_resident_objects FUN_00212e28\n\n* overlay: match the horny toad update FUN_L00_002d4610\n\nPorted from rac1-decomp func_L00_002D5AC0 (exact there). The start\nposition check and the case 10 step share one stack vector, as retail\ndoes.\n\n* overlay: migrate FUN_L00_00258830 (668 B)\n\n* overlay: migrate FUN_L10_002d85c8 (1588 B)\n\n* overlay: migrate FUN_L09_00304360 (1932 B)\n\n* overlay: migrate FUN_L10_002e3ef0 (2280 B)\n\n* overlay: migrate FUN_L06_002f4f00 (1120 B)\n\n* overlay: migrate FUN_L13_002e6c08 (1584 B)\n\n* overlay: migrate FUN_L05_00303390 (1908 B)\n\n* overlay: migrate FUN_L08_00307cf0 (2020 B)\n\n* decomp: migrate initialize_gameplay_sound_system (FUN_0022c8d0, 380 B)\n\n* overlay: migrate FUN_L00_001f58e0 (4884 B)\n\n* decomp: name the callees of the migrated functions and move initialize_gameplay_sound_system to audio/\n\n* overlay: keep FUN_L00_00258830 in 00257ef0.c, where main already has its C","measures":{"fuzzy_match_percent":79.33818,"total_code":3546268,"matched_code":2763884,"matched_code_percent":77.93782,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3762,"matched_functions_percent":88.87314,"complete_code":2763884,"complete_code_percent":77.93782,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":365}},{"timestamp":"2026-10-12T07:51:01Z","commit_sha":"caa7a158f6e26fd4b0f645b4588933075902e2c0","commit_message":"overlay: match the horny toad and moby update loop (#161)\n\n* decomp: name hero fields that were padding (0x238, 0x244, 0x934, 0x1024 group, 0x221C)\n\n* decomp: match update_visible_resident_objects FUN_00212e28\n\n* overlay: match the horny toad update FUN_L00_002d4610\n\nPorted from rac1-decomp func_L00_002D5AC0 (exact there). The start\nposition check and the case 10 step share one stack vector, as retail\ndoes.\n\n* decomp: name update_visible_resident_objects and use the shared Moby header\n\nMoves FUN_00212e28 to gameplay/entities/update_visible_resident_objects.c,\nreplaces its local Moby copy with rnc/gameplay/entities/moby.h, names the\nflag bits it tests and calls it by name from the scene frames.\nmake elf and make overlays PASS.\n\n* overlay: name horny_toad_update and its callees\n\nFUN_L00_002d4610 becomes horny_toad_update; its callees and globals use\ntheir existing names (camera_position, moby_table, fast-math helpers).\nCallees whose shared declarations in the unit conflict keep the unit-local\nspelling. make overlays PASS.","measures":{"fuzzy_match_percent":78.847755,"total_code":3546268,"matched_code":2746188,"matched_code_percent":77.43882,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3753,"matched_functions_percent":88.66052,"complete_code":2746188,"complete_code_percent":77.43882,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":365}},{"timestamp":"2026-10-12T04:33:25Z","commit_sha":"9e9cb4e2fd8ecbae36d3ab3720b0f2fd0a8eb617","commit_message":"decomp: improve resident and level overlay decompilation (#160)\n\n* decomp: improve sceDbcCreateSocket\n\n* decomp: improve _doMC\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve transition_do_transition\n\n* decomp: improve update_level_gameplay_frame\n\n* decomp: improve _doMC\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve render_configured_text_label\n\n* overlay: improve find_or_assign_bolt_source_slot\n\n* overlay: improve update_hoverboard_girl_boobs_animation\n\n* overlay: improve create_particle_at_moby_point\n\n* overlay: improve FUN_L06_002e9b60\n\n* overlay: improve print_sorted_moby_sizes\n\n* overlay: improve FUN_L00_00235668\n\n* overlay: improve FUN_L00_00299a68\n\n* overlay: improve draw_projected_fading_quad\n\n* overlay: improve update_hero_item_slots\n\n* overlay: improve FUN_L00_002831c0\n\n* overlay: improve FUN_L01_002c7530\n\n* overlay: improve FUN_L01_0030bfa8\n\n* overlay: improve FUN_L00_002997c8\n\n* overlay: improve update_hero_color_and_item_tint\n\n* overlay: improve FUN_L12_00303370\n\n* overlay: improve FUN_L00_002721f0\n\n* overlay: improve draw_debug_text\n\n* overlay: improve FUN_L01_00276fe8\n\n* overlay: improve nanotech_upgrade_vendor\n\n* overlay: improve initialize_camera_data\n\n* overlay: improve FUN_L00_002092c8\n\n* overlay: improve FUN_L00_00237840\n\n* overlay: improve FUN_L00_00261d78\n\n* overlay: improve FUN_L00_002995d0\n\n* overlay: improve FUN_L00_00275aa0\n\n* overlay: improve FUN_L06_002fd460\n\n* overlay: improve FUN_L12_00302c58\n\n* overlay: improve FUN_L08_002e9758\n\n* overlay: improve FUN_L05_00254058\n\n* overlay: improve update_hero_held_items_and_orientation\n\n* overlay: improve draw_group_quads\n\n* overlay: improve FUN_L00_0029ad08\n\n* overlay: improve FUN_L00_00262030\n\n* overlay: improve FUN_L00_0020a9e8\n\n* overlay: improve FUN_L12_00308350\n\n* overlay: improve FUN_L09_0021e560\n\n* overlay: improve update_linked_moby_scene_trigger\n\n* overlay: improve FUN_L00_002d5160\n\n* overlay: improve FUN_L02_00264e70\n\n* overlay: improve FUN_L14_002df138\n\n* overlay: improve FUN_L05_0030c5b0\n\n* overlay: improve spawn_troll_alert_particles\n\n* overlay: improve FUN_L00_00299c48\n\n* overlay: improve create_moby_with_particles\n\n* overlay: improve scan_hero_input_sequences\n\n* overlay: improve draw_rope_strips\n\n* overlay: improve FUN_L00_002056a8\n\n* overlay: improve FUN_L13_0030cdb8\n\n* overlay: improve FUN_L00_00228c18\n\n* overlay: improve FUN_L18_002ea1f8\n\n* overlay: improve FUN_L18_002f9eb8\n\n* overlay: improve FUN_L12_003028c8\n\n* overlay: improve FUN_L14_00314f00\n\n* overlay: improve FUN_L10_002dcc58\n\n* overlay: improve FUN_L11_003192c8\n\n* overlay: improve FUN_L00_002dd8e8\n\n* overlay: improve FUN_L15_002edfc0\n\n* overlay: improve FUN_L08_002d5950\n\n* overlay: improve FUN_L05_0030c220\n\n* overlay: improve FUN_L05_00266320\n\n* overlay: improve FUN_L05_002d7920\n\n* overlay: improve FUN_L01_0030b618\n\n* overlay: improve FUN_L05_00262b58\n\n* overlay: improve FUN_L11_0030b358\n\n* overlay: improve FUN_L00_0023fa00\n\n* overlay: improve FUN_L00_002d2670\n\n* overlay: improve draw_l07_effect_quads\n\n* overlay: improve FUN_L05_002f87a8\n\n* overlay: improve FUN_L00_00268900\n\n* overlay: improve FUN_L00_0020f160\n\n* overlay: improve launch_bomb\n\n* overlay: improve FUN_L10_002da2c8\n\n* overlay: improve FUN_L06_002d8738\n\n* overlay: improve FUN_L13_002c7f38\n\n* overlay: improve FUN_L14_002dfd10\n\n* overlay: improve vendor_draw_item_info\n\n* overlay: improve FUN_L07_0030cf90\n\n* overlay: improve FUN_L10_002e91b8\n\n* overlay: improve update_moby_state_and_usage_stats\n\n* overlay: improve FUN_L00_002caf70\n\n* overlay: improve build_packet_and_draw_scaled_entries\n\n* overlay: improve FUN_L07_00310df0\n\n* overlay: improve draw_quad_grid_with_dynamic_uvs\n\n* overlay: improve FUN_L07_0031d2e0\n\n* overlay: improve update_linked_moby_hitbox\n\n* overlay: improve FUN_L07_0031a9e8\n\n* overlay: improve FUN_L01_002b91c8\n\n* overlay: improve FUN_L07_0031aee0\n\n* overlay: improve FUN_L08_002d3878\n\n* overlay: improve update_moby_damage_reaction\n\n* overlay: improve FUN_L00_0023db30\n\n* overlay: improve FUN_L15_0029aff0\n\n* overlay: improve update_conditional_help_messages\n\n* overlay: improve FUN_L13_002c3fc0\n\n* overlay: improve FUN_L00_002d2158\n\n* overlay: improve FUN_L07_002f5ba0\n\n* overlay: improve FUN_L09_002c6230\n\n* overlay: improve FUN_L15_002e5958\n\n* overlay: improve FUN_L13_0030b628\n\n* overlay: improve FUN_L10_002da690\n\n* overlay: improve FUN_002bf140\n\n* overlay: improve FUN_L08_002f44c0\n\n* overlay: improve FUN_L10_002dfc38\n\n* overlay: improve FUN_L14_00301fa8\n\n* overlay: improve FUN_002e8210\n\n* overlay: improve FUN_L00_002d9810\n\n* overlay: improve FUN_L07_0030b000\n\n* overlay: improve FUN_L02_002ea210\n\n* overlay: improve FUN_L00_00276368\n\n* overlay: improve FUN_L04_0029ecf8\n\n* overlay: improve FUN_L06_002ffcb0\n\n* overlay: improve draw_hud_stars\n\n* overlay: improve FUN_L05_00253b48\n\n* overlay: improve FUN_L10_002e8ab0\n\n* overlay: improve update_moby_collision_and_fragments\n\n* overlay: improve FUN_L08_003024d8\n\n* overlay: improve update_quad_effect_2b3628\n\n* overlay: improve FUN_L08_002dc9a8\n\n* overlay: improve FUN_L11_003094f8\n\n* overlay: improve update_path_flyer_state\n\n* overlay: improve FUN_L10_002d85c8\n\n* overlay: improve FUN_L00_002ebe70\n\n* overlay: improve FUN_L08_00307540\n\n* overlay: improve FUN_L07_00319040\n\n* overlay: improve FUN_L00_00238f88\n\n* overlay: improve FUN_L14_003017f8\n\n* overlay: improve FUN_L00_002be078\n\n* overlay: improve FUN_L14_002b2928\n\n* overlay: improve update_linked_moby_state\n\n* overlay: improve FUN_L00_0020dd20\n\n* overlay: improve update_sentry_hit_reaction_and_visibility\n\n* overlay: improve FUN_L05_00262f50\n\n* overlay: improve FUN_L13_00305a58\n\n* overlay: improve FUN_L09_003091b0\n\n* overlay: improve FUN_L06_00307d30\n\n* overlay: improve FUN_L00_002a3ec8\n\n* overlay: improve FUN_L06_002f2250\n\n* overlay: improve update_moby_child_state\n\n* overlay: improve update_ship_pickup\n\n* overlay: improve FUN_L12_00304e00\n\n* overlay: improve FUN_L13_002cefc0\n\n* overlay: improve FUN_L06_003049f8\n\n* overlay: improve FUN_L00_00269d20\n\n* overlay: improve FUN_L18_002e9768\n\n* overlay: improve FUN_L07_0030d4d8\n\n* overlay: improve FUN_L00_002772c0\n\n* overlay: improve FUN_L08_002d23f0\n\n* overlay: improve predict_throw_landing\n\n* overlay: improve FUN_L13_0030a6d8\n\n* overlay: improve FUN_L00_002484e0\n\n* overlay: improve FUN_L06_00301b90\n\n* overlay: improve FUN_L00_0020f580\n\n* overlay: improve FUN_L09_00304360\n\n* overlay: improve FUN_L00_002a5040\n\n* overlay: improve FUN_L05_00305178\n\n* overlay: improve FUN_L06_002fa9c0\n\n* overlay: improve generate_random_points_from_shape_entries\n\n* overlay: improve update_hover_moby_steering\n\n* overlay: improve FUN_L07_0031a250\n\n* overlay: improve FUN_L00_002080b0\n\n* overlay: improve FUN_L08_00307cf0\n\n* overlay: improve FUN_L00_002d73e8\n\n* overlay: improve FUN_L00_002bc7e8\n\n* overlay: improve FUN_L00_0025c698\n\n* overlay: improve update_hero_ledge_probe\n\n* overlay: improve FUN_L00_00245c28\n\n* overlay: improve update_slot_panes_and_effects\n\n* overlay: improve FUN_L10_002be858\n\n* overlay: improve FUN_L06_002f5d78\n\n* overlay: improve FUN_L00_002382a0\n\n* overlay: improve FUN_L07_003112c8\n\n* overlay: improve FUN_L02_002d8ad0\n\n* overlay: improve FUN_L05_002d1688\n\n* overlay: improve update_camera_record\n\n* overlay: improve nearest_rail_point\n\n* overlay: improve FUN_L00_002cfcb8\n\n* overlay: improve update_spawned_moby\n\n* overlay: improve FUN_L00_002cb418\n\n* overlay: improve FUN_L05_0031bf40\n\n* overlay: improve FUN_L08_002d4ca0\n\n* overlay: improve update_orbit_camera_position\n\n* overlay: improve check_ledge_grab\n\n* overlay: improve FUN_L06_002f55a0\n\n* overlay: improve FUN_L10_002e3ef0\n\n* overlay: improve FUN_L00_002dbf28\n\n* overlay: improve update_moby_sequence\n\n* overlay: improve FUN_L08_002e2df0\n\n* overlay: improve FUN_L00_002b77f0\n\n* overlay: improve FUN_L00_002c1ad0\n\n* overlay: improve FUN_L00_002d09b8\n\n* overlay: improve FUN_L05_0030ca80\n\n* overlay: improve FUN_L15_002d7bb0\n\n* overlay: improve FUN_L00_002062b0\n\n* overlay: improve FUN_L00_0025e450\n\n* overlay: improve update_moby_state_and_emit_effects\n\n* overlay: improve FUN_L00_002cd1f0\n\n* overlay: improve FUN_L12_00303540\n\n* overlay: improve FUN_L00_002b6140\n\n* overlay: improve FUN_L08_002d2af0\n\n* overlay: improve FUN_L00_002d89f0\n\n* overlay: improve FUN_L02_002d93e8\n\n* overlay: improve FUN_L06_00252dd0\n\n* overlay: improve FUN_L00_002c6158\n\n* overlay: improve FUN_L01_002f5168\n\n* overlay: improve FUN_L00_002ce358\n\n* overlay: improve FUN_L18_002f88e8\n\n* overlay: improve FUN_L07_0026b768\n\n* overlay: improve FUN_L13_002ba178\n\n* overlay: improve update_debug_menu\n\n* overlay: improve FUN_L08_002deee0\n\n* overlay: improve FUN_L00_002ddf60\n\n* overlay: improve FUN_L00_002b49a8\n\n* overlay: improve FUN_L00_002c4380\n\n* overlay: improve FUN_L08_002f5e58\n\n* overlay: improve find_or_assign_bolt_source_slot\n\n* overlay: improve FUN_L08_002d6450\n\n* overlay: improve FUN_L00_00235668\n\n* overlay: improve FUN_L00_002b03a0\n\n* overlay: improve FUN_L05_003166a0\n\n* overlay: improve FUN_L02_002fb648\n\n* overlay: improve FUN_L01_002ef350\n\n* overlay: share swarm path and child declarations\n\n* overlay: share camera spring declarations\n\n* decomp: share help record declarations\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":78.76609,"total_code":3546268,"matched_code":2743292,"matched_code_percent":77.357155,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3752,"matched_functions_percent":88.6369,"complete_code":2743292,"complete_code_percent":77.357155,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":366}},{"timestamp":"2026-10-11T14:27:06Z","commit_sha":"4b156bb849b8829e9e361a7cb9bf0cb3ed976f23","commit_message":"overlay: merge the open decomp branches (#159)\n\n* chore: game compiler patch 0057, a trap is volatile for delay-slot filling\n\n* chore: game compiler reference cc1 hash with patch 0057\n\n* docs: relicense the repository under GPL-3.0\n\nrac1-decomp moved to GPL-3.0; Lombyte follows so its C can be ported again.\nCode taken while it was MIT keeps its notice.\n\n* overlay: port 24 level functions from rac1-decomp\n\nExact on the overlay proof; each carries its rac1-decomp origin.\n\n* decomp: mark fast_decompress as intentional assembly\n\n* overlay: port 6 more level functions from rac1-decomp\n\n* docs: add game folder\n\n* overlay: port 6 SN-built level functions from rac1-decomp\n\n* overlay: port 7 more level functions from rac1-decomp\n\n* overlay: port 8 more level functions from rac1-decomp\n\n* decomp: name the hero's attach anchor and ledge fields\n\nThe attach anchor (0x310-0x330), the attached moby's per-frame move and\nflags (0x350-0x364), and the ledge height and flags (0x4E0, 0x4F4), as the\nhero movement functions read them. Layout checks cover each one.\n\n* decomp: mark fill_transfer_words as intentional asm\n\nIt steps with addi, the trapping add; every compiler here emits addiu for\nthe same C.\n\n* overlay: stop the hero's sound slots (FUN_L00_00206c08)\n\nFor each of the hero's 8 sound slots it releases the voice if that voice\nstill belongs to the slot's moby (or the hero's own moby) and is playing,\nthen clears the slot.\n\n* docs: shorten the README licence note\n\n* overlay: port 2 more level functions from rac1-decomp\n\n* overlay: port 2 more level functions from rac1-decomp\n\n* overlay: port FUN_L11_00309ac0 from rac1-decomp\n\n* overlay: port 3 level functions from rac1-decomp and build their units with SN\n\n* overlay: port 3 more level functions from rac1-decomp\n\n* overlay: port FUN_L09_002eaea8 from rac1-decomp\n\n* overlay: port FUN_L06_002fc640 from rac1-decomp\n\n* docs: link the community Discord in the README\n\n* fix: keep main's cleaned-up code where both sides decompiled a function\n\nThe merge of main resolved whole conflicting files to this branch's side,\nwhich dropped main's struct-based versions (struct Moby, hero fields).\nMain's exact version now wins wherever both sides match retail; this\nbranch's code stays where main still had assembly or a NON_MATCHING draft.\n\n* chore: drop game compiler patch 0057\n\nNo function on this branch needs it: the boot ELF and every overlay\nfunction still match retail with the compiler built without it.\n\n* decomp: one name per called function in the ported level code\n\nPer-file aliases such as func_001F9F90_313800 or fast_cos_c2 now use the\nrecovered or most common name (FastCos, approach_value, ...), and duplicate\ndeclarations are dropped.\n\n* decomp: one name per called function in the Umbris moby code\n\n* decomp: struct Moby instead of local moby layouts in six level units\n\n* overlay: decompile FUN_L00_002e5830, the follow camera eye update\n\nPorted from rac1-decomp with the US data pairing: the zoom record is\nreached through D_L00_00166E00 (a .data pointer) and the base distance is\nthe gp float D_L00_00161CD8; the int-to-float and lerp callees are\nFUN_001fa6c0 and FUN_001f9a40. The camera state at UpdateCam +0x70 is typed\nas FollowCamState (focus, velocity, eased offset, eye, blend timer).\nByte-exact on the game compiler; make elf, make overlays and make check pass.\n\n* overlay: decompile FUN_L00_002e6000, the follow camera state tweaks\n\n* docs: rac1-decomp notice without its licence history\n\n(cherry picked from commit f75271b46e9b87ca2614ff89672f6052263b9d63)\n\n* docs: one ported-from header per function in level code\n\n(cherry picked from commit f791ea3a1a9b6b64de86d87e833f6dd54a43e8ec)\n\n* decomp: hud_send_resident_bank matches\n\nhud_send_resident_bank uploads one HUD bank's image pages to GS memory\nfrom the depth buffer address up. It matches once the depth buffer read\nis written in both arms of the link test (so the bank state address is\nnot carried across the call), the bank offset is taken before the first\npage index, and the end index is read through that offset.\n\n(cherry picked from commit f55a9c5d01ce27a79b59000a72912f7cf3728c07)\n\n* decomp: hud_send_resident_bank C source and its unit path\n\nThe previous commit only moved the file; this adds the matching C body\nand points the unit at src/ui/hud.\n\n(cherry picked from commit e072e8c28198d992fa93f97ecf334b3b431a9caa)\n\n* overlay: FUN_L01_002fad68 (agnogg ship update) ported from rac1-decomp\n\nThe planet-unlock state machine of the level 01 ship mobys, ported from\nrac1-decomp with its data paired to the US level program. The\npending-gadget word is read through an unsized array and the unlock table\nthrough a .sdata address, as retail splits them.\n\n(cherry picked from commit 77c65dda2786e9c06abe23b673695dda7edbeade)\n\n* overlay: FUN_L00_002adb30 (thrown bomb update) ported from rac1-decomp\n\n(cherry picked from commit a7d45c07e935ead25cd7f15641d73bacc58bbeb6)\n\n* overlay: mark FUN_L00_002502f0/00250320 as intentional asm\n\nRetail is hand-written: nop before jr $31 in 002502f0, $at used as a GPR\nin 00250320. Evidence comments only; unit also holds 00250430 (C goal),\nso unit_categories.json is unchanged.\n\n(cherry picked from commit 9d1d00506fa399404ef88cfc99fe69274199f6a4)\n\n* overlay: FUN_L00_0029a6b0 (vendor open) decompiled\n\n(cherry picked from commit e645edbd806d59e9c46c9435db27010b445f1e8d)\n\n* overlay: move vendor menu declarations above FUN_L00_0029ba78\n\n(cherry picked from commit a152ca73164f317293eee5b246d4d39e5d501597)\n\n* overlay: FUN_L00_0029ba78 (vendor buy/consume state machine) decompiled\n\n(cherry picked from commit ea6acd9afcc667d63035ba2bd6044751e5951a0c)\n\n* overlay: decompile FUN_L00_002e5830, the follow camera eye update\n\nPorted from rac1-decomp with the US data pairing: the zoom record is\nreached through D_L00_00166E00 (a .data pointer) and the base distance is\nthe gp float D_L00_00161CD8; the int-to-float and lerp callees are\nFUN_001fa6c0 and FUN_001f9a40. The camera state at UpdateCam +0x70 is typed\nas FollowCamState (focus, velocity, eased offset, eye, blend timer).\nByte-exact on the game compiler; make elf, make overlays and make check pass.\n\n(cherry picked from commit 3f509e51b93380b754236d30eb1c26af9ad9fafe)\n\n* overlay: decompile FUN_L00_002a84c8, the wrench swing and throw update\n\nPorted from rac1-decomp; the unit now builds with SN cc1, so the sda\nexterns of FUN_L00_002a4cd8 are spelled one per line and FUN_L00_002a9c50\nreads its spin angles through an array alias.\n\n(cherry picked from commit 14467ae916e709c368056d01f5f00a6df5b6313c)\n\n* overlay: decompile FUN_L00_002a5dd8, the bolt pickup update\n\n(cherry picked from commit 7a513218223e9e33c08b6df6946934f0ec560573)\n\n* overlay: decompile FUN_L00_002e6000, the follow camera state tweaks\n\n(cherry picked from commit 17b3b7ab5e862e6f6e9e8f42976d72e36b1fb9fc)\n\n* decomp: gameplay loader FUN_L00_00241940 in C (SN unit)\n\nPorted from rac1-decomp func_L00_002422D8. The unit now builds with SN:\nthe moby spawn test's movz flags and the cuboid copy loop only match there.\nSymbols re-paired against the US listing; the group-list count goes to\nD_L00_0015FFF4.\n\n(cherry picked from commit 5f519c0e6c4704af4a050655ad89ab862d64579e)\n\n* decomp: hero input update FUN_L00_00211670 in C\n\n(cherry picked from commit 9e6e6a13057dc78b411afddcf6ceb90d24dee525)\n\n* decomp: hero ledge probe FUN_L00_00221310 in C\n\nLoop copies of h, base and lim with dead stores to the originals keep\nGCSE from propagating them back into the loop, which reproduces retail's\nregister shuffle before the probe loop.\n\n(cherry picked from commit 77099cec3bc191ffcbf60d855b55be519b504fa0)\n\n* decomp: hero velocity update FUN_L00_00214108 in C\n\nBuilds the unit with SN. The tail clamp keeps the floor call result in its\nown register only while a later (never-true) use keeps it alive through\ncombine; that use is folded away after allocation, as in retail.\n\n(cherry picked from commit 608da52c3b44c948e7366b1270ed0eea508fb86b)\n\n* decomp: lower_snake_case names in the merged demo functions\n\n* decomp: clean hero ledge probe loop, label the velocity clamp hypothesis\n\nFUN_L00_00221310: the loop now spells its constants (1.1f, 0.0f, 0.5f)\nlike the code before it; loop hoisting plus cse2 give retail's two\nregister copies, so the dead stores and copy variables are gone.\nFUN_L00_00214108: the comment on the never-true test now says it is a\nhypothesis and gives the retail evidence (g kept live in its own\nregister with no visible reader).\n\n* decomp: shot cameras FUN_L00_002ec988 and FUN_L00_002ed498 in C\n\nBoth set up the rig with the same shape: the rig pointer in its own\nlocal, q, the track, the blend end and the copy e taken from it in that\norder, st from e. That keeps the loaded pointer out of a saved register\nand gives the retail copy and scheduling.\n\n* decomp: shot cameras FUN_L00_002ec988 and FUN_L00_002ed498 in C\n\nBoth set up the rig with the same shape: the rig pointer in its own\nlocal, q, the track, the blend end and the copy e taken from it in that\norder, st from e. That keeps the loaded pointer out of a saved register\nand gives the retail copy and scheduling. Replaces the NON_MATCHING body\nof FUN_L00_002ed498.\n\n* decomp: FUN_L00_00213e68 air steering as NON_MATCHING C\n\n* overlay: name the volume shot cameras and their fields\n\nvolume_camera_swing and volume_camera_aim replace FUN_ names, the\nfollow camera setters get names, the aim shot record becomes a struct\nand the hero position/up vector use the hero struct.\n\n* overlay: clean up the volume cameras\n\nThe swing and aim cameras and their checks (volume_camera_swing_active,\nvolume_camera_swing, volume_camera_swing_check, volume_camera_aim_active,\nvolume_camera_aim, volume_camera_check) now share one descriptor and one\nparameter struct per camera type instead of per-function copies.\n\nThe follow camera state moves to include/rnc/gameplay/camera/follow_cam.h,\nwith the fields these cameras write and a layout check. The boot math\nhelpers get one header (fast_math.h) with their recovered names, and the\nremaining unnamed callees use lower-case fun_ names.","measures":{"fuzzy_match_percent":78.17505,"total_code":3546268,"matched_code":2722332,"matched_code_percent":76.76611,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3739,"matched_functions_percent":88.32979,"complete_code":2722332,"complete_code_percent":76.76611,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":365}},{"timestamp":"2026-10-11T11:59:51Z","commit_sha":"d05ba33621a747ffb8acb86e6904e30af57d477b","commit_message":"docs: add cleanup guide (#158)\n\n* docs: add cleanup guide and reference it from CONTRIBUTING\n\n* docs: rename cleanup guide to code-cleanup.md\n\n* docs: simplify code cleanup guide structure and wording","measures":{"fuzzy_match_percent":78.08312,"total_code":3546268,"matched_code":2719072,"matched_code_percent":76.67419,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3737,"matched_functions_percent":88.28254,"complete_code":2719072,"complete_code_percent":76.67419,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":365}},{"timestamp":"2026-10-11T11:52:39Z","commit_sha":"648a654b1e027a78a49ca4934c95c1993babe921","commit_message":"decomp: decompilerizer batch 11 (#157)\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve FUN_L08_002d6450\n\n* decomp: improve find_or_assign_bolt_source_slot\n\n* decomp: improve FUN_L00_00299a68\n\n* decomp: improve print_sorted_moby_sizes\n\n* decomp: improve restore_or_clear_level_state\n\n* decomp: improve draw_projected_fading_quad\n\n* decomp: improve FUN_L00_001fc558\n\n* decomp: improve FUN_L00_002997c8\n\n* decomp: improve FUN_L00_002076a8\n\n* decomp: improve FUN_L01_0030bfa8\n\n* decomp: improve FUN_L00_00236268\n\n* decomp: improve FUN_L00_00261968\n\n* decomp: improve FUN_L00_002db8f8\n\n* decomp: improve update_hero_item_slots\n\n* decomp: improve nanotech_upgrade_vendor\n\n* decomp: improve FUN_L01_002b8f98\n\n* decomp: improve FUN_L00_00261b48\n\n* decomp: improve FUN_L13_002e97e0\n\n* decomp: improve FUN_L00_002092c8\n\n* decomp: improve FUN_L01_00263a28\n\n* decomp: improve FUN_L08_002e2250\n\n* decomp: improve FUN_L01_00276fe8\n\n* decomp: improve initialize_level_graphics_frame_effect_state\n\n* decomp: improve FUN_L00_002c35c0\n\n* decomp: improve FUN_L00_0020a9e8\n\n* decomp: improve FUN_L06_002fd1a0\n\n* decomp: improve FUN_L00_0026b230\n\n* decomp: improve FUN_L00_001fcca0\n\n* decomp: improve FUN_L00_00299c48\n\n* decomp: improve FUN_L15_002bddb0\n\n* decomp: improve emit_moby_particles\n\n* decomp: improve FUN_L05_00254058\n\n* decomp: improve FUN_L00_002637f8\n\n* decomp: improve update_hero_held_items_and_orientation\n\n* decomp: improve scan_hero_input_sequences\n\n* decomp: improve FUN_L14_002df138\n\n* decomp: improve FUN_L01_002b8cb0\n\n* decomp: improve FUN_L12_00308350\n\n* decomp: improve FUN_L08_002de528\n\n* decomp: improve FUN_L13_002ed158\n\n* decomp: improve FUN_L00_00262030\n\n* decomp: improve draw_rotated_textured_quad\n\n* decomp: improve FUN_L09_0021e560\n\n* decomp: improve FUN_L00_0029ff58\n\n* decomp: improve FUN_L02_00264e70\n\n* decomp: improve FUN_L00_002b6bc8\n\n* decomp: improve FUN_L00_0023a2d0\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve FUN_L15_002edbe0\n\n* decomp: improve FUN_L01_002ef770\n\n* decomp: improve FUN_L05_0030c5b0\n\n* decomp: improve draw_segmented_ui_bar\n\n* decomp: improve FUN_L12_003028c8\n\n* decomp: improve FUN_L13_0030cdb8\n\n* decomp: improve spawn_troll_alert_particles\n\n* decomp: improve FUN_L18_002f9eb8\n\n* decomp: improve draw_rope_strips\n\n* decomp: improve FUN_L00_002056a8\n\n* decomp: improve FUN_L01_00319928\n\n* decomp: improve FUN_L18_002ea1f8\n\n* decomp: improve FUN_L05_0030c220\n\n* decomp: improve find_nearest_path_point\n\n* decomp: improve FUN_L11_003192c8\n\n* decomp: improve FUN_L12_00302f30\n\n* decomp: improve FUN_L10_002dcc58\n\n* decomp: improve FUN_L06_002ff2c8\n\n* decomp: improve FUN_L10_002f5b58\n\n* decomp: improve update_gemlik_trail\n\n* decomp: improve FUN_L05_002f87a8\n\n* decomp: improve update_route_following_moby\n\n* decomp: improve resolve_level_candidate_position\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve FUN_L12_002e8808\n\n* decomp: improve FUN_L05_00262b58\n\n* decomp: improve FUN_L05_00266320\n\n* decomp: improve FUN_L05_002d7920\n\n* decomp: improve FUN_L00_002ed498\n\n* decomp: improve FUN_L01_0030b618\n\n* decomp: improve FUN_L00_0023fa00\n\n* decomp: improve spawn_particles_from_joint\n\n* decomp: improve FUN_L14_002de670\n\n* decomp: improve FUN_L14_00314f00\n\n* decomp: improve FUN_L15_001ff938\n\n* decomp: improve FUN_L08_002e5188\n\n* decomp: improve FUN_L13_002c7f38\n\n* decomp: improve update_linked_moby_hitbox\n\n* decomp: improve FUN_L00_00268900\n\n* decomp: improve FUN_L00_002464a8\n\n* decomp: improve FUN_L00_002d2670\n\n* decomp: improve FUN_L00_002bf9f0\n\n* decomp: improve FUN_L00_0025ff38\n\n* decomp: improve FUN_L10_002e91b8\n\n* decomp: improve FUN_L06_002d8738\n\n* decomp: improve FUN_L07_0030cf90\n\n* decomp: improve FUN_L15_002a3138\n\n* decomp: improve FUN_L15_002d0fa8\n\n* decomp: improve FUN_L14_002dfd10\n\n* decomp: improve FUN_L00_002caf70\n\n* decomp: improve FUN_L00_002bc3b0\n\n* decomp: improve build_packet_and_draw_scaled_entries\n\n* decomp: improve update_path_spawn_state\n\n* decomp: improve FUN_L13_002c3fc0\n\n* decomp: improve FUN_L18_002d82c0\n\n* decomp: improve FUN_L00_0023db30\n\n* decomp: improve update_help_effect\n\n* decomp: improve FUN_L07_00310df0\n\n* decomp: improve draw_quad_grid_with_dynamic_uvs\n\n* decomp: improve FUN_L15_0029aff0\n\n* decomp: improve FUN_L07_0031a9e8\n\n* decomp: improve FUN_L01_002b91c8\n\n* decomp: improve update_conditional_help_messages\n\n* decomp: improve FUN_L09_002f86a0\n\n* decomp: improve FUN_L13_002e4448\n\n* decomp: improve FUN_L08_002d3878\n\n* decomp: improve FUN_L07_0031aee0\n\n* decomp: improve FUN_L00_00237200\n\n* decomp: improve FUN_L07_00313420\n\n* decomp: improve FUN_L00_002c7548\n\n* decomp: improve FUN_L15_002e5958\n\n* decomp: improve FUN_L00_002d2158\n\n* decomp: improve FUN_L05_00253b48\n\n* decomp: improve FUN_L10_002dfc38\n\n* decomp: improve FUN_L07_002f5ba0\n\n* decomp: improve FUN_L13_0030b628\n\n* decomp: improve draw_hud_stars\n\n* decomp: improve FUN_L13_002cefc0\n\n* decomp: improve FUN_L09_003082d8\n\n* decomp: improve FUN_L07_0030b000\n\n* decomp: improve FUN_L09_002c6230\n\n* decomp: improve FUN_L14_002b2928\n\n* decomp: improve FUN_002e8ab0\n\n* decomp: improve FUN_L08_003024d8\n\n* decomp: improve FUN_L00_00276368\n\n* decomp: improve FUN_L00_002d9810\n\n* decomp: improve update_spark_emitter\n\n* decomp: improve FUN_L14_00301fa8\n\n* decomp: improve FUN_L02_002ea210\n\n* decomp: improve FUN_0029ecf8\n\n* decomp: improve FUN_L06_002ffcb0\n\n* decomp: improve FUN_L00_00238f88\n\n* decomp: improve FUN_L13_002c2048\n\n* decomp: improve update_path_flyer_state\n\n* decomp: improve FUN_L13_00306300\n\n* decomp: improve FUN_L06_002feb40\n\n* decomp: improve FUN_L00_002ebe70\n\n* decomp: improve FUN_L10_002d85c8\n\n* decomp: improve FUN_L14_003017f8\n\n* decomp: improve build_interpolated_dma_packet\n\n* decomp: improve update_vendor_slot_moby\n\n* decomp: improve FUN_L15_0029a570\n\n* decomp: improve FUN_L08_00307540\n\n* decomp: improve FUN_L13_002c2d30\n\n* decomp: improve update_motion_and_emit_effects\n\n* decomp: improve FUN_L05_00262f50\n\n* decomp: improve FUN_L07_00319040\n\n* decomp: improve FUN_L06_00303160\n\n* decomp: improve FUN_L00_0020dd20\n\n* decomp: improve FUN_002fbfb0\n\n* decomp: improve FUN_L06_00307d30\n\n* decomp: improve update_leg_rig_motion\n\n* decomp: improve FUN_L06_002f2250\n\n* decomp: improve FUN_L13_00305a58\n\n* decomp: improve FUN_00304e00\n\n* decomp: improve update_path_camera\n\n* decomp: improve FUN_L18_002e9768\n\n* decomp: improve update_ship_pickup\n\n* decomp: improve FUN_L06_003049f8\n\n* decomp: improve FUN_L01_002eec68\n\n* decomp: improve FUN_L00_00269d20\n\n* decomp: improve FUN_L00_002772c0\n\n* decomp: improve FUN_L06_002fa9c0\n\n* decomp: improve FUN_L00_0020f580\n\n* decomp: improve FUN_L08_002d23f0\n\n* decomp: improve FUN_L00_002a5040\n\n* decomp: improve FUN_L05_00305178\n\n* decomp: improve predict_throw_landing\n\n* decomp: improve FUN_L13_0030a6d8\n\n* decomp: improve FUN_L00_002484e0\n\n* decomp: improve FUN_L00_002080b0\n\n* decomp: improve FUN_L09_00304360\n\n* decomp: improve FUN_L06_002f5d78\n\n* decomp: improve generate_random_points_from_shape_entries\n\n* decomp: improve FUN_L06_00301b90\n\n* decomp: improve FUN_L07_0031a250\n\n* decomp: improve update_hover_moby_steering\n\n* decomp: improve FUN_L15_002ed398\n\n* decomp: improve FUN_L10_002be858\n\n* decomp: improve FUN_L05_002d7140\n\n* decomp: improve FUN_L15_002a7880\n\n* decomp: improve scatter_ground_particles\n\n* decomp: improve update_hero_ledge_probe\n\n* decomp: improve FUN_L06_002f55a0\n\n* decomp: improve update_red_button\n\n* decomp: improve FUN_L00_002d73e8\n\n* decomp: improve FUN_L00_0025c698\n\n* decomp: improve check_ledge_grab\n\n* decomp: improve FUN_L02_002d8ad0\n\n* decomp: improve FUN_L07_003112c8\n\n* decomp: improve FUN_L00_00245c28\n\n* decomp: improve FUN_L05_002d1688\n\n* decomp: improve FUN_L00_00260a88\n\n* decomp: improve FUN_L00_002cb418\n\n* decomp: improve update_hoverboard_girl\n\n* decomp: improve update_camera_record\n\n* decomp: improve FUN_L00_002cfcb8\n\n* decomp: improve update_slot_panes_and_effects\n\n* decomp: improve FUN_L10_002e3ef0\n\n* decomp: improve FUN_L08_002d4ca0\n\n* decomp: improve FUN_L00_002382a0\n\n* decomp: improve update_spawned_moby\n\n* decomp: improve FUN_L05_0031bf40\n\n* decomp: improve update_moby_sequence\n\n* decomp: improve steer_child_moby\n\n* decomp: improve FUN_L00_002cc608\n\n* decomp: improve FUN_L00_002c1ad0\n\n* decomp: improve update_moby_state_and_emit_effects\n\n* decomp: improve FUN_L00_002062b0\n\n* decomp: improve FUN_L06_00302578\n\n* decomp: improve FUN_L00_002dbf28\n\n* decomp: improve update_orbit_camera_position\n\n* decomp: improve update_drain_cover\n\n* decomp: improve FUN_L00_002d09b8\n\n* decomp: improve handle_hero_gadget_button\n\n* decomp: improve FUN_L00_002b77f0\n\n* decomp: improve FUN_L05_0030ca80\n\n* decomp: improve FUN_L12_002e3ed8\n\n* decomp: improve FUN_L08_002e2df0\n\n* decomp: improve UpdatePathAndParticleSlots\n\n* decomp: improve FUN_L15_002d7bb0\n\n* decomp: improve FUN_L00_002d4610\n\n* decomp: improve FUN_L00_002cd1f0\n\n* decomp: improve FUN_L00_0025e450\n\n* decomp: improve update_parented_moby\n\n* decomp: improve FUN_L12_00303540\n\n* decomp: improve FUN_L00_002b6140\n\n* decomp: improve FUN_L00_002d89f0\n\n* decomp: improve FUN_L00_002c6158\n\n* decomp: improve FUN_L00_002d3a10\n\n* decomp: improve FUN_L01_002f5168\n\n* decomp: improve FUN_L00_002ce358\n\n* decomp: improve FUN_L02_002d93e8\n\n* fix: preserve upstream hero fields and overlay addressing\n\n* decomp: improve FUN_L06_00252dd0\n\n* decomp: improve FUN_L01_002edca0\n\n* decomp: improve FUN_L00_002b49a8\n\n* decomp: improve FUN_L00_002c4380\n\n* decomp: improve FUN_L07_0026b768\n\n* decomp: improve update_jet_fighter\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":78.08312,"total_code":3546268,"matched_code":2719072,"matched_code_percent":76.67419,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3737,"matched_functions_percent":88.28254,"complete_code":2719072,"complete_code_percent":76.67419,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":365}},{"timestamp":"2026-10-11T09:55:48Z","commit_sha":"b105c7d92679d52d7b0290c758bdbf218bdeed7a","commit_message":"overlay: 27 Oltanis and 6 Veldin 2 functions (#156)\n\n* overlay: oltanis bolt update (1152 B)\n\nFUN_L14_002ece00. Port of FUN_L07_0030b6a8 with Oltanis pvars, plus a sweep that retries past class 0xFC mobys; the collision result is one struct at D_L14_00174540 (moby at 0x18, point at 0x20), which gives retail's base-minus-0x20 addressing.\n\n* overlay: oltanis lift update (1180 B)\n\nFUN_L14_002e7bd8. The rider flag clear is stored before the class default is read (keeps retail's two flag stores) and both height lerps take the timer ratio in a block-scoped temporary. qcopy.h moves to the top includes.\n\n* overlay: oltanis engine exhaust puffs (1192 B)\n\nFUN_L14_002fc3e8. Puff record struct for FUN_L00_0026d000 (prototype from the Eudora trail code); the velocity table is la-addressed (MACRO_ADDR), the tail pointer is block-scoped, the puff loops and ring loops use separate counters, and the ring frame is set before the life.\n\n* overlay: oltanis drifting mine update (1244 B)\n\nFUN_L14_002ec810. The explosion call takes FUN_L00_0025e450's four-float prototype (fixes the arg-setup order); the path lengths are indexed as floats with the store address formed after the call, and the colour is built as g << 16 | (0xFF000000 | g << 8) | r.\n\n* overlay: oltanis second engine exhaust (1272 B)\n\nFUN_L14_002fd310. Sibling of FUN_L14_002fc3e8 with a grey middle puff: the middle puff has its own block-scoped pointer, the grey colour is 0x7F000000 | g << 16 | g << 8 | g, and its size is set before the offset is applied. The puff struct gains its alpha byte at 0x03.\n\n* overlay: oltanis vendor platform update (1668 B)\n\nFUN_L14_002ee8d8. Typed pvars struct; FUN_L00_0025b8c0 is declared with the target before the velocity pointer (same registers, but the nested itof argument then only forces &level into a saved register, as in retail); -1 stores ordered for the scheduler.\n\n* overlay: oltanis wind emitter update (1024 B)\n\nFUN_L14_002eaf88. A no-op re-store of the spark weight behind a branch keeps the FUN_L14_002eb568 argument move in its own block until after scheduling; FUN_L14_002eb388 declared void, and the push scale reads D_0015ED6C into a local first.\n\n* overlay: oltanis tram update (1888 B)\n\nFUN_L14_002fcbb0. The rider's unk32 is set to the constant 0xFF like unk30 (cse reuses the compared item byte register for it, retail's sh of that register), not to the item byte itself.\n\n* overlay: oltanis spark update (680 B)\n\nFUN_L14_002eb568. Each branch divides by its own age (the shared tail is cross-jumped), pos/shade set up and stepped in that order, and a no-op re-store of the shade raises its allocation priority.\n\n* overlay: oltanis blarg interceptor update (1580 B)\n\nFUN_L14_00306ee0, ported from rac1-decomp (func_L14_00308368 in src/overlays/l14_oltanis/vendor_002FF358.c), exact with US names and addresses; the pvars layout stays file-local.\n\n* overlay: oltanis camera 21 update (2556 B)\n\nFUN_L14_00315d48, ported from rac1-decomp (func_L14_003171D0 in src/overlays/l14_oltanis/vendor_002FF358.c). Their SN build matches as written; on the game compiler two unused reads (key table, next index) before the side tests are needed to hoist the table high half and index load as retail does.\n\n* overlay: oltanis path flyer update (1028 B)\n\nFUN_L14_00307620. The pitch target goes through a variable before the\napproach call (otherwise its pointer arguments are computed before the\nnested calls), FUN_L00_0025f090 is declared (moby, pos, f32, f32, int),\nand the rider's flag/position stores follow retail's order.\n\n* overlay: oltanis path flyer plain mobies base declaration\n\nFUN_L14_00307620 still matches with a plain declaration of D_L14_0015FFD8. The sda form made\nPs2EeAs address that symbol through $gp for the rest of the file, which later functions do not do.\n\n* overlay: oltanis spinning beam draw (864 B)\n\nFUN_L14_002add48. A for loop for the sixteen steps (retail inherits the spilled counter in $16),\nthe colour and uv stores in reverse of their schedule, and size/step grown before the colour clamps.\n\n* overlay: oltanis nearest path point pick (252 B)\n\nFUN_L14_002f1040. Typed pvars and path-point structs give retail's strength-reduced loop; the picked index is read once into a local before the two quadword copies.\n\n* overlay: oltanis cart update (756 B)\n\nFUN_L14_002fc0f0. Typed pvars struct (its field stores no longer alias the moby, so the case-0 constant loads schedule like retail); error strings are the D_L14_001FCE10/D_L14_001FCE48 symbols; callee aliases renamed descriptively.\n\n* overlay: oltanis rail length setup (496 B)\n\nFUN_L14_002eef60. Plain indexed for loops over the two rails (loop.c makes the point pointers), with the first rail read through a copy of its pointer.\n\n* overlay: oltanis taxi ship update (2820 B)\n\nFUN_L14_002f0538, ported from rac1-decomp (func_L14_002F19C0 in src/overlays/l14_oltanis/vendor_002E0538.c), exact on the first build with US names and addresses.\n\n* overlay: oltanis rail length setup: drop duplicate declaration from rebase\n\n* overlay: oltanis ribbon draw (1860 B)\n\nFUN_L14_002df510. Two textured quads swept along a path per segment (glow and core), modelled on the\nported FUN_L14_002edc18. Needed: qcopy() for every vector copy, the second texture lookup before the inner\ncolour, colour stores written col[3]..col[0] (outer colour as one chained expression so SN shifts it in\nplace), inner colours before the copied GIF words, and the highlight restore in the same order.\n\n* overlay: oltanis racer glow quads (668 B)\n\nFUN_L14_002d71f0. Separate counters for the two quad loops (the extra callee-saved pseudo stops\nthe D_0013F5E0 high part living across loop 1), constant colours, and the packet header stored\nb, d, c, a.\n\n* overlay: oltanis path flyer main update (4768 B)\n\nFUN_L14_002ac618, the ten-state update (cases 1->2 and 3->4 fall through).\nCase 9 uses &m->pos directly: retail's extra pointer copy is a GCSE PRE\nreaching register. FUN_L00_0025b8c0 is declared (pos, target, vel, ...).\n\n* overlay: oltanis vendor camera run (1676 B)\n\nFUN_L14_00315290. The argument is struct UpdateCam; the stop table at p+0x58 is a struct of\nseg[8]/fov[8] indexed as arrays, the main loop tests seg[i] and seg[i+1] with no separate j (which let\ngcse keep j*2), and the done branch writes cam->transition_state as a struct field.\n\n* overlay: oltanis racer update (2476 B)\n\nFUN_L14_002d67e8. The track position reads go through a small struct view of the vars\n(struct access lets the frac load move above the segment store), the particle table is\ndeclared in .sdata (one la), and the else arm keeps its new state in a local.\n\n* overlay: oltanis bouncing spark (1756 B)\n\nFUN_L14_00300e00. The trail particle call uses the true FUN_L00_0026d000 argument order\n(pos, three floats, spin, texture, size, colour), the texture table is declared in .sdata,\nand the hit/next position copy is written once per branch (retail cross-jumps the tails).\n\n* overlay: oltanis vendor camera start (880 B)\n\nFUN_L14_003159d8. The duration fix-up loop is written with a goto so the\nskip branch is an EQ test (reorg then annuls the store like retail); the\nblend-state pointer is read through struct UpdateCam.\n\n* overlay: oltanis ring lights draw (816 B)\n\nFUN_L14_002ada18. The matrix and the transformed ring live in one local struct, so the second\nloop addresses the ring through the struct and is not merged with the first by gcse; that gives\nretail's preheader order.\n\n* overlay: oltanis flying debris (1684 B)\n\nFUN_L14_002bac78. The light colour and range are locals initialised at the\ntop (range 3.0, green 0.8, blue 0.2): reload rematerialises them at each\nstore, which gives retail's $f0/$f1 rotation; stores in order range, r, g, b.\n\n* overlay: oltanis lightning arc setup (1768 B)\n\nFUN_L14_002ed530. Taking p's address in the clamp ((*&p)[2]) is what\ngives retail's register choice for the E0000/DFD80 bases before the first\nloop; the CB4/CEC store order needs the chained assignment.\n\n* overlay: oltanis vendor platform: follow the frames_off_ground rename (#153)\n\n* overlay: veldin 2 level core data load (4260 B)\n\nFUN_L18_002463f8 is the same code as the shared FUN_L00_00244110 with this\nlevel's data addresses. Like that unit it is SN-compiled, so the file joins\nOVERLAY_SN_UNITS (the two other functions in it stay exact under SN).\n\n* overlay: veldin 2 spinning ring quads draw (1116 B)\n\nFUN_L18_002dba20, ported from rac1-decomp's near miss for func_L18_002DCE10.\nThe two float tuning globals read in the t/radius setup are declared as\nfloat (not read through a cast), which lets their loads schedule early.\n\n* overlay: veldin 2 fading ring quads draw (1116 B)\n\nFUN_L18_002dc4b8, ported from rac1-decomp's near miss for func_L18_002DD8A8.\nThe float globals are declared as float, and the corner z is one ternary\nstore. That form gives gcse a hash table size where the PRE copies of the\nstack addresses get retail's pseudo order, so their spill slots match.\n\n* overlay: veldin 2 thruster pack lock update (1092 B)\n\nFUN_L18_002d7b20, from the in-file draft. Case 4 updates help record 0x71\nthrough a pointer to the help records (count, best play time, level mask),\nwith the RECORD_BEST style compare, a `one` variable for the level bit, plain\ncurrent_level_index, and FUN_0022da68 declared as returning int.\n\n* overlay: veldin 2 vendor camera follow update (1048 B)\n\nFUN_L18_002f7288, ported from rac1-decomp (func_L18_002F86E8).\nThe camera approach helper FUN_00213f38 returns float; the void\nprototype swapped two loads before its calls.\n\n* overlay: veldin 2 vendor boss hit update (2548 B)\n\nFUN_L18_002f5e80, ported from rac1-decomp (func_L18_002F72E0); exact\nwith the US callees and globals (hero.state.control_mode, hero.moby).","measures":{"fuzzy_match_percent":77.318825,"total_code":3546268,"matched_code":2691968,"matched_code_percent":75.90989,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3722,"matched_functions_percent":87.928185,"complete_code":2691968,"complete_code_percent":75.90989,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":364}},{"timestamp":"2026-10-11T09:17:45Z","commit_sha":"9ffb0aaec71482ba97948819da7922757ee939f2","commit_message":"overlay: name the Novalis gunship, pool tiles, hint and cutscene helpers (#155)\n\nReplace the per-function gs_/pool_/l01_/fx_ aliases with the names the\nrest of the tree uses for the same engine functions and globals, name the\ngunship fields by use (trigger and beam volumes, cutscene camera and timer,\nstop nodes, base scale and speed) and spell D_L01_0015F5C4 and\nD_L01_0015F5CC one way per file. All functions stay exact.","measures":{"fuzzy_match_percent":75.90009,"total_code":3546268,"matched_code":2641656,"matched_code_percent":74.49116,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3690,"matched_functions_percent":87.17222,"complete_code":2641656,"complete_code_percent":74.49116,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":361}},{"timestamp":"2026-10-11T09:00:09Z","commit_sha":"cbbd890d68e7a2400816de4340b5d1c0a6b78ab7","commit_message":"overlay: five Novalis functions (#154)\n\n* overlay: novalis gunship update (2716 B)\n\nFUN_L01_002f7728, ported from rac1-decomp (func_L01_002F8B00); only the US banner id and addresses differ.\n\n* overlay: novalis tutorial hint triggers (2396 B)\n\nFUN_L01_0030acb8, written after the Kerwan triggers in l03 (FUN_L03_002df520), on the shared hero, usage_stats and level_available types. The 0x43 bit test is spelled \"< 1\" so cc1 keeps the sllv/and form.\n\n* overlay: novalis pool tiles controller (2232 B)\n\nFUN_L01_002fd0e8, written after the l11/l13 tile-pool mobys. The case-0 tile field stores are in the order that schedules like retail; fresh loop variables per loop and a few base-pointer locals keep retail's register use.\n\n* overlay: novalis cutscene effects (1796 B)\n\nFUN_L01_0030c190. The effect list is passed as &D_L01_0015F580 (the file's\nsmall s32 declaration) and fx_prev_pos is MACRO_ADDR, so their addresses are\nrebuilt per use like retail and only the cutscene high part stays in $30.\nSeparate counters per loop, and the scene-5 copy is duplicated in both arms\n(cross-jumped) so cse does not carry addresses over the join.\n\n* overlay: novalis path node picker (1120 B)\n\nFUN_L01_002e6790. The phase-2 scan stores the pick inside its exit branch\n(for (;;) ... if (*idx == 0) { *idx = best; break; }), which keeps that\nstore ahead of the result compare like retail; the result is assigned back\nto i so i, not best, stays the cse class head for the neighbour tests.","measures":{"fuzzy_match_percent":75.90009,"total_code":3546268,"matched_code":2641656,"matched_code_percent":74.49116,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3690,"matched_functions_percent":87.17222,"complete_code":2641656,"complete_code_percent":74.49116,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":361}},{"timestamp":"2026-10-11T08:40:23Z","commit_sha":"103e2a882701edd580597144fca2009f97355600","commit_message":"decomp: name hero, camera, weapon and pad code from research findings (#153)\n\n* decomp: name hero fields for platform carry, ground type, attacks and reach\n\n* decomp: name hero, camera, weapon, crate and HUD functions in the level code\n\n* check: follow the hero field renames\n\n* decomp: name level tables for attacks, fidgets, items, hits and HUD elements\n\n* decomp: name the pad button bits\n\n* decomp: name the hero state ids\n\n* fix: count named overlay functions whose label follows a macro","measures":{"fuzzy_match_percent":75.61077,"total_code":3546268,"matched_code":2631396,"matched_code_percent":74.201836,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3685,"matched_functions_percent":87.0541,"complete_code":2631396,"complete_code_percent":74.201836,"complete_data":0,"complete_data_percent":0,"total_units":511,"complete_units":358}},{"timestamp":"2026-10-11T07:46:39Z","commit_sha":"901f09012c6396b5c513251d462960a5166b9798","commit_message":"overlay: Veldin gameplay, hero, camera, wrench and vendor functions in C (#151)\n\n* docs: rac1-decomp notice without its licence history\n\n(cherry picked from commit f75271b46e9b87ca2614ff89672f6052263b9d63)\n\n* docs: one ported-from header per function in level code\n\n(cherry picked from commit f791ea3a1a9b6b64de86d87e833f6dd54a43e8ec)\n\n* decomp: hud_send_resident_bank matches\n\nhud_send_resident_bank uploads one HUD bank's image pages to GS memory\nfrom the depth buffer address up. It matches once the depth buffer read\nis written in both arms of the link test (so the bank state address is\nnot carried across the call), the bank offset is taken before the first\npage index, and the end index is read through that offset.\n\n(cherry picked from commit f55a9c5d01ce27a79b59000a72912f7cf3728c07)\n\n* decomp: hud_send_resident_bank C source and its unit path\n\nThe previous commit only moved the file; this adds the matching C body\nand points the unit at src/ui/hud.\n\n(cherry picked from commit e072e8c28198d992fa93f97ecf334b3b431a9caa)\n\n* overlay: FUN_L01_002fad68 (agnogg ship update) ported from rac1-decomp\n\nThe planet-unlock state machine of the level 01 ship mobys, ported from\nrac1-decomp with its data paired to the US level program. The\npending-gadget word is read through an unsized array and the unlock table\nthrough a .sdata address, as retail splits them.\n\n(cherry picked from commit 77c65dda2786e9c06abe23b673695dda7edbeade)\n\n* overlay: FUN_L00_002adb30 (thrown bomb update) ported from rac1-decomp\n\n(cherry picked from commit a7d45c07e935ead25cd7f15641d73bacc58bbeb6)\n\n* overlay: mark FUN_L00_002502f0/00250320 as intentional asm\n\nRetail is hand-written: nop before jr $31 in 002502f0, $at used as a GPR\nin 00250320. Evidence comments only; unit also holds 00250430 (C goal),\nso unit_categories.json is unchanged.\n\n(cherry picked from commit 9d1d00506fa399404ef88cfc99fe69274199f6a4)\n\n* overlay: FUN_L00_0029a6b0 (vendor open) decompiled\n\n(cherry picked from commit e645edbd806d59e9c46c9435db27010b445f1e8d)\n\n* overlay: move vendor menu declarations above FUN_L00_0029ba78\n\n(cherry picked from commit a152ca73164f317293eee5b246d4d39e5d501597)\n\n* overlay: FUN_L00_0029ba78 (vendor buy/consume state machine) decompiled\n\n(cherry picked from commit ea6acd9afcc667d63035ba2bd6044751e5951a0c)\n\n* overlay: decompile FUN_L00_002e5830, the follow camera eye update\n\nPorted from rac1-decomp with the US data pairing: the zoom record is\nreached through D_L00_00166E00 (a .data pointer) and the base distance is\nthe gp float D_L00_00161CD8; the int-to-float and lerp callees are\nFUN_001fa6c0 and FUN_001f9a40. The camera state at UpdateCam +0x70 is typed\nas FollowCamState (focus, velocity, eased offset, eye, blend timer).\nByte-exact on the game compiler; make elf, make overlays and make check pass.\n\n(cherry picked from commit 3f509e51b93380b754236d30eb1c26af9ad9fafe)\n\n* overlay: decompile FUN_L00_002a84c8, the wrench swing and throw update\n\nPorted from rac1-decomp; the unit now builds with SN cc1, so the sda\nexterns of FUN_L00_002a4cd8 are spelled one per line and FUN_L00_002a9c50\nreads its spin angles through an array alias.\n\n(cherry picked from commit 14467ae916e709c368056d01f5f00a6df5b6313c)\n\n* overlay: decompile FUN_L00_002a5dd8, the bolt pickup update\n\n(cherry picked from commit 7a513218223e9e33c08b6df6946934f0ec560573)\n\n* overlay: decompile FUN_L00_002e6000, the follow camera state tweaks\n\n(cherry picked from commit 17b3b7ab5e862e6f6e9e8f42976d72e36b1fb9fc)\n\n* decomp: gameplay loader FUN_L00_00241940 in C (SN unit)\n\nPorted from rac1-decomp func_L00_002422D8. The unit now builds with SN:\nthe moby spawn test's movz flags and the cuboid copy loop only match there.\nSymbols re-paired against the US listing; the group-list count goes to\nD_L00_0015FFF4.\n\n(cherry picked from commit 5f519c0e6c4704af4a050655ad89ab862d64579e)\n\n* decomp: hero input update FUN_L00_00211670 in C\n\n(cherry picked from commit 9e6e6a13057dc78b411afddcf6ceb90d24dee525)\n\n* decomp: hero ledge probe FUN_L00_00221310 in C\n\nLoop copies of h, base and lim with dead stores to the originals keep\nGCSE from propagating them back into the loop, which reproduces retail's\nregister shuffle before the probe loop.\n\n(cherry picked from commit 77099cec3bc191ffcbf60d855b55be519b504fa0)\n\n* decomp: hero velocity update FUN_L00_00214108 in C\n\nBuilds the unit with SN. The tail clamp keeps the floor call result in its\nown register only while a later (never-true) use keeps it alive through\ncombine; that use is folded away after allocation, as in retail.\n\n(cherry picked from commit 608da52c3b44c948e7366b1270ed0eea508fb86b)\n\n* decomp: lower_snake_case names in the merged demo functions\n\n* decomp: clean hero ledge probe loop, label the velocity clamp hypothesis\n\nFUN_L00_00221310: the loop now spells its constants (1.1f, 0.0f, 0.5f)\nlike the code before it; loop hoisting plus cse2 give retail's two\nregister copies, so the dead stores and copy variables are gone.\nFUN_L00_00214108: the comment on the never-true test now says it is a\nhypothesis and gives the retail evidence (g kept live in its own\nregister with no visible reader).\n\n* sdk: classify sceVu0RotMatrixZ as intentional VU0 assembly\n\nRetail FUN_001252b8 moves the angle with qmtc2 and transforms the rows\nwith lqc2/sqc2 and vmulax/vmadday/vmaddaz/vmaddw, which C cannot\nexpress. Drop the NON_MATCHING draft and list the unit in\nintentional_asm.\n\n* decomp: read_mpeg FUN_0023a460 in C\n\nThe movie input pump. It matches with each pad test as an inline helper\ntaking the pad by pointer (retail forms the pad address afresh per test),\nthe skip mode cached in a local for the -1 and 2 tests and read again\nin the skip-allowed test (declared volatile, as retail repeats that\nload), and separate locals for the put space and the get count.\n\n* decomp: render_level_effects_and_screen_sprites FUN_002196b8 in C\n\n* decomp: FUN_002196b8 C body and splat entry for the moved unit\n\n* decomp: build_indexed_resident_render_packet FUN_00202d78 in C\n\nBuilds the four-word GS texture packet for a resident class material.\nIt matches when the TEX1 word goes through a separate filter local and is\nbuilt in the textured branch only (the other branches store their\nexpression directly), height_log2 is s32, the TEX0 format bits get their\nown local, and the TEX0 and MIP words are assembled in retail's grouping\nwith the TEX0 store ahead of the MIP store.\n\n* decomp: hero platform carry FUN_L00_00233f80 in C (SN unit)\n\nPorted from rac1-decomp (src/overlays/shared/help_00232560.c:\nfunc_L00_00234800), names translated to the US level program. The unit is\nalready built with SN cc1; all 48 functions in it stay exact. make overlays:\n2502/2502.\n\n* decomp: hero gadget/weapon input FUN_L00_00227fa0 in C (SN unit)\n\nPorted from rac1-decomp (src/overlays/shared/help_00221A98.c:\nfunc_L00_00228770), names translated to the US level program. Called by the\nstate switch FUN_L00_00229b70. The unit is already built with SN cc1 and all\nits C functions stay exact. make overlays: 2503/2503.\n\n* sdk: cut sceVu0Normalize FUN_00125180 out of text gap 001250d8 as intentional VU0 assembly\n\nRetail 0x125180..0x1251bc is libvu0's sceVu0Normalize: lqc2, vmul.xyz,\nvaddy/vaddz, vsqrt/vwaitq, vdiv, vmulq.xyz and sqc2 on VU0 macro mode,\nwhich C cannot emit. The gap is split (split-gap-functions.py) and the new\nunit is listed in intentional_asm. Called by the Veldin hero movement.\n\n* decomp: follow-camera reset FUN_L00_002e5e38 in C (SN unit)\n\n* decomp: animation blend step FUN_L00_0024f190 in C (SN unit)\n\n* decomp: spline walk FUN_L00_0025d808 in C\n\n* classify FUN_001fa2b8 and fast_normalize_angle FUN_001fa610 as intentional fastfunc assembly\n\n* fast_normalize_angle: state the interleaved $at evidence against a ps2eeas reassembly\n\n* decomp: hero creation FUN_L00_00204c60 in C (own SN unit)\n\n* decomp: hero animation frame advance FUN_L00_00232670 in C (own SN unit)\n\nThe overlay proof now places a candidate's own literal-pool constant\n(.sdata/.lit4/.lit8) at the address retail's lui/load pair names, after\nchecking that the level holds the same bytes there.\n\n* decomp: hero ledge/collision state check FUN_L00_00227778 in C (own SN unit)\n\n* decomp: FUN_L00_00227778 uses a separate void prototype instead of a call-site cast\n\n* decomp: hero pose table update FUN_L00_00215340 in C (own SN unit)\n\n* decomp: hero idle fidget picker FUN_L00_00229010 in C\n\n* decomp: hero item moby spawner FUN_L00_0020ea80 in C\n\n* decomp: list unlink and free FUN_L00_0024f0e8 in C\n\n* decomp: animation frame packet builder FUN_L00_0024f440 in C\n\n* decomp: follow-camera orientation update FUN_L00_002e9010 in C\n\n* decomp: quad-strip effect draw FUN_L00_002a7780 in C\n\n* decomp: promote draw_checking_memory_card_data_menu (FUN_00220348)\n\nThe memory-card \"checking data\" screen matches once every return 2 goes\nthrough one shared exit label, first is computed inside the flags & 4\ntest, the preview texture is fetched in both arms of the state test, and\nthe page is read as menu_system.current.\n\n* decomp: vendor list build FUN_L00_0029a400 in C\n\n* decomp: hero/level class block loader FUN_L00_00244110 in C\n\n* decomp: follow-camera leaf FUN_L00_002e7d20 in C\n\n* decomp: update_view_context FUN_001f2d98 in C\n\nThe 8388112.0f screen bias is held in a local set at entry, so its single\nuse is re-emitted at the store and shares $f0 with proj3[0]; the proj3,\ninverse scale and screen bias stores are in their natural order.\n\n* decomp: name the idle fidget picker's fields and helpers\n\n* decomp: use the shared names for per-file aliases in the PR's units\n\n* decomp: mark the FUN_L00_00214108 clamp as a fakematch","measures":{"fuzzy_match_percent":75.53915,"total_code":3546268,"matched_code":2628856,"matched_code_percent":74.13021,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4233,"matched_functions":3684,"matched_functions_percent":87.03047,"complete_code":2628856,"complete_code_percent":74.13021,"complete_data":0,"complete_data_percent":0,"total_units":512,"complete_units":358}},{"timestamp":"2026-10-11T05:04:30Z","commit_sha":"81cbed22fa375a031f903adb0869dd5584186f77","commit_message":"decomp: decompilerizer batch 10 (#152)\n\n* decomp: improve kputchar\n\n* decomp: improve transition_do_transition\n\n* decomp: improve update_menu_grid_selection\n\n* decomp: improve sound_update\n\n* decomp: improve update_streamed_moby_animation\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve sound_update\n\n* decomp: improve FUN_L00_00264740\n\n* decomp: improve FUN_L08_002d6450\n\n* decomp: improve find_or_assign_bolt_source_slot\n\n* decomp: improve FUN_L12_003094a0\n\n* decomp: improve FUN_L00_0024f440\n\n* decomp: improve FUN_L14_002f1040\n\n* decomp: improve FUN_L00_00235668\n\n* decomp: improve update_hoverboard_girl_boobs_animation\n\n* decomp: improve print_sorted_moby_sizes\n\n* decomp: improve initialize_render_archive_transfer\n\n* decomp: improve FUN_L00_00299a68\n\n* decomp: improve FUN_L00_002648e0\n\n* decomp: improve FUN_L00_002997c8\n\n* decomp: improve update_hero_item_slots\n\n* decomp: improve FUN_L08_00316fa8\n\n* decomp: improve FUN_L00_0026b500\n\n* decomp: improve FUN_L01_00263a28\n\n* decomp: improve FUN_L08_002e2250\n\n* decomp: improve FUN_L01_0028bb90\n\n* decomp: improve adjust_hero_velocity\n\n* decomp: improve FUN_L01_002b8f98\n\n* decomp: improve FUN_L00_002995d0\n\n* decomp: improve FUN_L14_002eb568\n\n* decomp: improve FUN_L00_002ebbd8\n\n* decomp: improve FUN_L00_00237840\n\n* decomp: improve FUN_L00_002cbcc0\n\n* decomp: improve FUN_L05_00254358\n\n* decomp: improve FUN_L00_0020a9e8\n\n* decomp: improve FUN_L00_0020cd08\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve FUN_L12_00302c58\n\n* decomp: improve FUN_L04_002923b8\n\n* decomp: improve FUN_L08_002e9758\n\n* decomp: improve scan_hero_input_sequences\n\n* decomp: improve FUN_L14_002fc0f0\n\n* decomp: improve FUN_L01_002b8cb0\n\n* decomp: improve FUN_L05_00254058\n\n* decomp: improve FUN_L08_002de528\n\n* decomp: improve FUN_L12_00308350\n\n* decomp: improve FUN_L15_002c4f88\n\n* decomp: improve FUN_L00_0020e728\n\n* decomp: improve update_linked_moby_scene_trigger\n\n* decomp: improve FUN_L13_002ed158\n\n* decomp: improve FUN_L00_00262030\n\n* decomp: improve FUN_L18_002f0390\n\n* decomp: improve FUN_L11_00310cf8\n\n* decomp: improve FUN_L00_0029ff58\n\n* decomp: improve FUN_L00_00214fe8\n\n* decomp: improve FUN_L09_0021e560\n\n* decomp: improve FUN_L14_002add48\n\n* decomp: improve FUN_L02_00264e70\n\n* decomp: improve FUN_L14_002df138\n\n* decomp: improve FUN_L00_00204c60\n\n* decomp: improve FUN_L01_002ef770\n\n* decomp: improve FUN_L00_002d5160\n\n* decomp: improve update_escalator_motion\n\n* decomp: improve FUN_L18_002f9780\n\n* decomp: improve FUN_L06_002fd748\n\n* decomp: improve build_vendor_menu_rows\n\n* decomp: improve update_route_following_moby\n\n* decomp: improve FUN_L00_0023a2d0\n\n* decomp: improve FUN_L14_00306b78\n\n* decomp: improve FUN_L01_0030c9a8\n\n* decomp: improve FUN_L00_002056a8\n\n* decomp: improve FUN_L15_002edbe0\n\n* decomp: improve FUN_L00_00211670\n\n* decomp: improve FUN_L00_00285008\n\n* decomp: improve FUN_L05_0024bdc0\n\n* decomp: improve FUN_L00_00261b48\n\n* decomp: improve spawn_troll_alert_particles\n\n* decomp: improve FUN_L00_002831c0\n\n* decomp: improve FUN_L00_002be650\n\n* decomp: improve FUN_L01_00315de0\n\n* decomp: improve FUN_L14_00305758\n\n* decomp: improve FUN_L06_002fd460\n\n* decomp: improve FUN_L00_0026b230\n\n* decomp: improve FUN_L00_002bed90\n\n* decomp: improve FUN_L06_00249738\n\n* decomp: improve FUN_003028c8\n\n* decomp: improve FUN_L13_0030cdb8\n\n* decomp: improve FUN_L00_002b1de0\n\n* decomp: improve FUN_L05_0030c5b0\n\n* decomp: improve draw_rope_strips\n\n* decomp: improve FUN_L00_001fc558\n\n* decomp: improve FUN_L14_002eef60\n\n* decomp: improve FUN_L00_00228c18\n\n* decomp: improve FUN_L01_002c7530\n\n* decomp: improve FUN_L00_0029ad08\n\n* decomp: improve FUN_L06_002d8178\n\n* decomp: improve FUN_L14_003159d8\n\n* decomp: improve FUN_L09_0030a778\n\n* decomp: improve FUN_L18_002f9eb8\n\n* decomp: improve FUN_L00_0023d198\n\n* decomp: improve FUN_L12_002ec720\n\n* decomp: improve FUN_L01_00319928\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L18_002ea1f8\n\n* decomp: improve FUN_L15_002edfc0\n\n* decomp: improve find_nearest_path_point\n\n* decomp: improve FUN_L11_003192c8\n\n* decomp: improve FUN_L10_002dcc58\n\n* decomp: improve FUN_L00_00299c48\n\n* decomp: improve spawn_class_1b3_projectile\n\n* decomp: improve FUN_L00_002dd8e8\n\n* decomp: improve FUN_L05_0030c220\n\n* decomp: improve FUN_L14_00314f00\n\n* decomp: improve FUN_L12_00302f30\n\n* decomp: improve FUN_L06_002ff2c8\n\n* decomp: improve FUN_L14_00301de8\n\n* decomp: improve FUN_L00_00229010\n\n* decomp: improve FUN_L05_002d7920\n\n* decomp: improve FUN_L00_002e7618\n\n* decomp: improve FUN_L11_0030b358\n\n* decomp: improve FUN_L10_002da2c8\n\n* decomp: improve FUN_L08_002d5950\n\n* decomp: improve FUN_L10_002f5b58\n\n* decomp: improve update_gemlik_trail\n\n* decomp: improve FUN_L10_002e5be0\n\n* decomp: improve FUN_L07_0030dcf0\n\n* decomp: improve FUN_L00_00257218\n\n* decomp: improve FUN_L05_00262b58\n\n* decomp: improve FUN_L00_002464a8\n\n* decomp: improve FUN_L14_002eaf88\n\n* decomp: improve FUN_L12_002e8808\n\n* decomp: improve FUN_L00_0023fa00\n\n* decomp: improve FUN_L00_002bf9f0\n\n* decomp: improve FUN_L00_0020f160\n\n* decomp: improve FUN_L01_0030b618\n\n* decomp: improve FUN_L00_002d2670\n\n* decomp: improve FUN_L05_002f87a8\n\n* decomp: improve FUN_L00_002ed498\n\n* decomp: improve FUN_L05_00316258\n\n* decomp: improve FUN_L00_002acfd8\n\n* decomp: improve update_linked_moby_hitbox\n\n* decomp: improve FUN_L08_002e5188\n\n* decomp: improve FUN_L15_001ff938\n\n* decomp: improve FUN_L18_002f7288\n\n* decomp: improve FUN_L13_002c7f38\n\n* decomp: improve FUN_L00_00268900\n\n* decomp: improve FUN_L14_002de670\n\n* decomp: improve FUN_L00_002bc3b0\n\n* decomp: improve FUN_L14_002de1f8\n\n* decomp: improve FUN_L01_002e6790\n\n* decomp: improve FUN_L18_002d7b20\n\n* decomp: improve FUN_L00_0025ff38\n\n* decomp: improve FUN_L00_0029ead8\n\n* decomp: improve FUN_L10_002d7b80\n\n* decomp: improve FUN_L06_002d8738\n\n* decomp: improve FUN_L13_002c3fc0\n\n* decomp: improve FUN_L15_002d0fa8\n\n* decomp: improve FUN_L07_0030cf90\n\n* decomp: improve FUN_L15_002a3138\n\n* decomp: improve FUN_L07_0031d2e0\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":73.866356,"total_code":3546584,"matched_code":2564392,"matched_code_percent":72.30597,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4236,"matched_functions":3649,"matched_functions_percent":86.142586,"complete_code":2564392,"complete_code_percent":72.30597,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":346}},{"timestamp":"2026-10-10T14:53:14Z","commit_sha":"8ae3b8ff1cd3db64e03f0b58c2b49113d6556e9d","commit_message":"decomp: lower_snake_case function names (#150)\n\n* decomp: lower_snake_case names for functions called by alias\n\nCamelCase C names (recovered symbols such as FastDiffRots or FastVecAdd)\nthat only alias an asm label now use the descriptive snake_case name the\nrest of the code already uses (fast_difference_between_rotations,\nadd_vector_xyz), or a snake_case spelling of the symbol. Sony SDK names,\nrecovered-symbol aliases and INCLUDE_ASM lines are unchanged.\nCONTRIBUTING gains the naming rule.\n\n* decomp: lower_snake_case for functions linked by name","measures":{"fuzzy_match_percent":73.57966,"total_code":3546584,"matched_code":2554224,"matched_code_percent":72.01927,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4236,"matched_functions":3635,"matched_functions_percent":85.81209,"complete_code":2554224,"complete_code_percent":72.01927,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":346}},{"timestamp":"2026-10-10T14:31:47Z","commit_sha":"f4f5f4af41d2f4fa684d7c23cb748e9a8dd584c2","commit_message":"decomp: decompilerizer batch 9 (#149)\n\n* decomp: improve kputchar\n\n* decomp: improve signal_native_cd_delay_alarm\n\n* decomp: improve ftoi\n\n* decomp: improve update_visible_resident_objects\n\n* decomp: improve LoadDefaultMpegQuantizerMatrix\n\n* decomp: improve hud_send_resident_bank\n\n* decomp: improve select_world_object_resource_tables\n\n* decomp: improve render_vendor_buy_label_pass\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve read_mpeg\n\n* decomp: improve _sceFs_Rcv_Intr\n\n* decomp: improve update_streamed_moby_animation\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve update_level_gameplay_frame\n\n* decomp: improve update_preview_animation_and_attachments\n\n* decomp: improve update_mode_freeze\n\n* decomp: improve FUN_001e9b10\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve draw_map_overlay\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve sound_update\n\n* decomp: improve FUN_0022abc0\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve update_streamed_moby_animation\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve transition_do_transition\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve render_level_effects_and_screen_sprites\n\n* decomp: improve render_vendor_capture_pass_sequence\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve render_vendor_capture_pass_sequence\n\n* decomp: improve sound_update\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve FUN_001e9b10\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve FUN_L00_002bcf98\n\n* decomp: improve interpolate_vector4_linear\n\n* decomp: improve find_or_assign_bolt_source_slot\n\n* decomp: improve FUN_L08_002d6450\n\n* decomp: improve initialize_moby_rotation_from_level_table\n\n* decomp: improve FUN_L00_00264740\n\n* decomp: improve FUN_L00_00235668\n\n* decomp: improve FUN_L12_003094a0\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve FUN_L14_002f1040\n\n* decomp: improve spawn_class_1b3_projectile\n\n* decomp: improve FUN_L02_002fb648\n\n* decomp: improve FUN_L00_0024f440\n\n* decomp: improve update_hoverboard_girl_boobs_animation\n\n* decomp: improve FUN_L00_002df808\n\n* decomp: improve FUN_L12_00306828\n\n* decomp: improve FUN_L00_00299a68\n\n* decomp: improve initialize_render_archive_transfer\n\n* decomp: improve FUN_L00_00241788\n\n* decomp: improve FUN_L09_00305a28\n\n* decomp: improve FUN_L00_00261968\n\n* decomp: improve draw_projected_fading_quad\n\n* decomp: improve FUN_L00_001fc558\n\n* decomp: improve FUN_L00_002e5e38\n\n* decomp: improve FUN_L00_00285008\n\n* decomp: improve FUN_L06_002f6dd0\n\n* decomp: improve FUN_L00_00261b48\n\n* decomp: improve FUN_L00_002db8f8\n\n* decomp: improve FUN_L01_002c7530\n\n* decomp: improve FUN_L12_00303370\n\n* decomp: improve FUN_L07_00311eb8\n\n* decomp: improve FUN_L00_002721f0\n\n* decomp: improve FUN_L14_002eef60\n\n* decomp: improve FUN_L14_00301de8\n\n* decomp: improve FUN_L00_00227778\n\n* decomp: improve FUN_L00_0023d198\n\n* decomp: improve FUN_L00_002be650\n\n* decomp: improve FUN_L14_002e0170\n\n* decomp: improve FUN_L00_00257218\n\n* decomp: improve FUN_L01_00315de0\n\n* decomp: improve FUN_L13_002e97e0\n\n* decomp: improve nanotech_upgrade_vendor\n\n* decomp: improve FUN_L00_002092c8\n\n* decomp: improve FUN_L09_0030a778\n\n* decomp: improve FUN_L01_00276fe8\n\n* decomp: improve profile_moby_updates\n\n* decomp: improve FUN_L00_001f3770\n\n* decomp: improve FUN_L00_002997c8\n\n* decomp: improve FUN_L00_002ebbd8\n\n* decomp: improve FUN_L01_00234358\n\n* decomp: improve FUN_L01_0028bb90\n\n* decomp: improve FUN_L00_002ddcb8\n\n* decomp: improve FUN_L00_002cbcc0\n\n* decomp: improve FUN_L01_00263a28\n\n* decomp: improve FUN_L01_002b8f98\n\n* decomp: improve FUN_0026b500\n\n* decomp: improve FUN_L14_002d71f0\n\n* decomp: improve FUN_L08_00316fa8\n\n* decomp: improve draw_scaled_record_with_progress\n\n* decomp: improve FUN_L08_002e2250\n\n* decomp: improve FUN_L05_00254358\n\n* decomp: improve FUN_L00_0020a9e8\n\n* decomp: improve FUN_L06_002fd1a0\n\n* decomp: improve FUN_L00_00221310\n\n* decomp: improve FUN_L00_002c35c0\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve FUN_L00_00275aa0\n\n* decomp: improve FUN_L00_002995d0\n\n* decomp: improve FUN_L04_002923b8\n\n* decomp: improve FUN_L08_002e9758\n\n* decomp: improve FUN_L00_00206e00\n\n* decomp: improve FUN_L06_002fd460\n\n* decomp: improve FUN_L00_001fcca0\n\n* decomp: improve FUN_L14_002fc0f0\n\n* decomp: improve FUN_L15_002bddb0\n\n* decomp: improve FUN_L14_00305758\n\n* decomp: improve FUN_L12_00302c58\n\n* decomp: reuse upstream overlay path table declaration\n\n* decomp: consolidate shared state and rendering layouts\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":73.57966,"total_code":3546584,"matched_code":2554224,"matched_code_percent":72.01927,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4236,"matched_functions":3635,"matched_functions_percent":85.81209,"complete_code":2554224,"complete_code_percent":72.01927,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":346}},{"timestamp":"2026-10-10T11:24:27Z","commit_sha":"86bb333ea4bed382f37b51fb5301e92ecf62bab6","commit_message":"fix: update Discord invite link (#148)","measures":{"fuzzy_match_percent":73.57966,"total_code":3546584,"matched_code":2554224,"matched_code_percent":72.01927,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4236,"matched_functions":3635,"matched_functions_percent":85.81209,"complete_code":2554224,"complete_code_percent":72.01927,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":346}},{"timestamp":"2026-10-10T11:10:02Z","commit_sha":"a1379f571f427797987f0b16e173188e74e87a25","commit_message":"overlay: 53 ported and 1 own level function, relicense under GPL-3.0 (#146)\n\n* chore: game compiler patch 0057, a trap is volatile for delay-slot filling\n\n* chore: game compiler reference cc1 hash with patch 0057\n\n* docs: relicense the repository under GPL-3.0\n\nrac1-decomp moved to GPL-3.0; Lombyte follows so its C can be ported again.\nCode taken while it was MIT keeps its notice.\n\n* overlay: port 24 level functions from rac1-decomp\n\nExact on the overlay proof; each carries its rac1-decomp origin.\n\n* decomp: mark fast_decompress as intentional assembly\n\n* overlay: port 6 more level functions from rac1-decomp\n\n* docs: add game folder\n\n* overlay: port 6 SN-built level functions from rac1-decomp\n\n* overlay: port 7 more level functions from rac1-decomp\n\n* overlay: port 8 more level functions from rac1-decomp\n\n* decomp: name the hero's attach anchor and ledge fields\n\nThe attach anchor (0x310-0x330), the attached moby's per-frame move and\nflags (0x350-0x364), and the ledge height and flags (0x4E0, 0x4F4), as the\nhero movement functions read them. Layout checks cover each one.\n\n* decomp: mark fill_transfer_words as intentional asm\n\nIt steps with addi, the trapping add; every compiler here emits addiu for\nthe same C.\n\n* overlay: stop the hero's sound slots (FUN_L00_00206c08)\n\nFor each of the hero's 8 sound slots it releases the voice if that voice\nstill belongs to the slot's moby (or the hero's own moby) and is playing,\nthen clears the slot.\n\n* docs: shorten the README licence note\n\n* overlay: port 2 more level functions from rac1-decomp\n\n* overlay: port 2 more level functions from rac1-decomp\n\n* overlay: port FUN_L11_00309ac0 from rac1-decomp\n\n* overlay: port 3 level functions from rac1-decomp and build their units with SN\n\n* overlay: port 3 more level functions from rac1-decomp\n\n* overlay: port FUN_L09_002eaea8 from rac1-decomp\n\n* overlay: port FUN_L06_002fc640 from rac1-decomp\n\n* docs: link the community Discord in the README\n\n* fix: keep main's cleaned-up code where both sides decompiled a function\n\nThe merge of main resolved whole conflicting files to this branch's side,\nwhich dropped main's struct-based versions (struct Moby, hero fields).\nMain's exact version now wins wherever both sides match retail; this\nbranch's code stays where main still had assembly or a NON_MATCHING draft.\n\n* chore: drop game compiler patch 0057\n\nNo function on this branch needs it: the boot ELF and every overlay\nfunction still match retail with the compiler built without it.\n\n* decomp: one name per called function in the ported level code\n\nPer-file aliases such as func_001F9F90_313800 or fast_cos_c2 now use the\nrecovered or most common name (FastCos, approach_value, ...), and duplicate\ndeclarations are dropped.\n\n* decomp: one name per called function in the Umbris moby code\n\n* decomp: struct Moby instead of local moby layouts in six level units\n\n* docs: rac1-decomp notice without its licence history\n\n* docs: one ported-from header per function in level code","measures":{"fuzzy_match_percent":73.57966,"total_code":3546584,"matched_code":2554224,"matched_code_percent":72.01927,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4236,"matched_functions":3635,"matched_functions_percent":85.81209,"complete_code":2554224,"complete_code_percent":72.01927,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":346}},{"timestamp":"2026-10-10T10:36:19Z","commit_sha":"42adb5293bb806c76f6b99f5867589bfd62a49f4","commit_message":"decomp: name five hero movement fields from live testing (#147)\n\n* decomp: name three hero movement fields from live testing\n\nunk194 -> ground_speed (horizontal speed target: 0.095 per frame while running, 5.7 u/s at 60 fps, 0 idle), motion.unk160 -> speed_xy (current horizontal speed, eased toward it and capped at frame_time * 52), unk920 -> move_impulse (one-frame displacement the hero update adds to motion.pos and clears; zero while running). Observed in PCSX2 with live memory reads and a write breakpoint on motion.pos. No code change.\n\n* decomp: name hero target_speed and speed_scale from live testing\n\nunk190 -> target_speed (ground_speed eases toward it via the approach helper; the stick handler writes it, 0 with the stick centred), unkA6C -> speed_scale (multiplier in target = frame_time * 5.7 * speed_scale, 1.0 normally). No code change.","measures":{"fuzzy_match_percent":71.49575,"total_code":3547428,"matched_code":2480920,"matched_code_percent":69.93574,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3581,"matched_functions_percent":84.51735,"complete_code":2480920,"complete_code_percent":69.93574,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":342}},{"timestamp":"2026-10-10T08:47:35Z","commit_sha":"c9a03b5fcdafe2b11403167bb0aa09d566e5d64e","commit_message":"overlay: finish Pokitaru, plus three boot units (#145)\n\n* decomp: promote advance_accelerated_scalar (456 B)\n\napproach_value is declared with its real float return (as in its own unit),\nwhich keeps the two velocity tails apart without the old comma hack.\n\n* decomp: promote cd disk-ready query fun_00121190 (504 B)\n\nClearing the bind flag inside the break branch (loop-weighted refs) and writing\nthe sceCdSyncS failure path out in full (merged by cross-jumping) gives the\nretail global-alloc order; replaces the old if (mode) x = 0; else x = 0; hack.\n\n* decomp: promote _type2id (136 B)\n\nThe mask table has three entries (0xFF00000000, 0xFFFF000000, 0xFFFFFFFFFF):\na real switch with the cases in the order 0xFFFFFFFFFF, 0xFFFF000000,\n0xFF00000000 gives retail's compare tree and frame; the old pad hack is gone.\n\n* overlay: pokitaru path creature moby update (5712 B)\n\nFUN_L11_00314318. The turn helper FUN_L00_0025be00 is declared returning\nfloat (as in l18); with a void prototype the scheduler moved the angle copy\nahead of the &d->unk250 argument in the path-follow state.\n\n* overlay: pokitaru creature turn and move update (780 B)\n\nFUN_L11_002d1030. Fakematch: a no-op store of the 0x154 speed back to\nitself in the clamp branch keeps the load live there, so sched1 hoists\nit and it gets $f4; reload deletes the store.\n\n* overlay: pokitaru chain path spread (324 B)\n\nFUN_L11_003180a0. The masked list index is one variable shared by both loops,\nso it is not block-local: local-alloc no longer ties the shift to it and the\nclass-id load takes $2 in the second loop, as in retail.\n\n* overlay: pokitaru tilting platform update (624 B)\n\nFUN_L11_0030eb90. The pvars go through a struct (field stores do not alias the\nscalar globals, so the flag store and hero address schedule as in retail), and\nthe spin update is two statements, which gives retail's FP registers.\n\n* overlay: pokitaru path platform update (2492 B)\n\nFUN_L11_00309ac0. FUN_00213f38 takes two pointers and four floats and\nreturns float (as advance_accelerated_scalar); the old draft passed a\nthird pointer, which forced the e8/ec register hacks. With the real\nprototype only the PRE spill-slot order was left: `prev_seq - 1 != 0`\nis one insn shorter before gcse, giving the 267-bucket hash table that\nnumbers the reaching registers in retail order. Case 2 reads the new\npath entry through a float pointer for retail's register choice.","measures":{"fuzzy_match_percent":71.49575,"total_code":3547428,"matched_code":2480920,"matched_code_percent":69.93574,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3581,"matched_functions_percent":84.51735,"complete_code":2480920,"complete_code_percent":69.93574,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":342}},{"timestamp":"2026-10-10T05:35:14Z","commit_sha":"6c2fc570f6185caffd804544dbe02518f3eaf1ad","commit_message":"decomp: read the hero through struct Hero in the remaining level functions (#140)\n\n* decomp: read the hero through struct Hero in FUN_L16_002e6208\n\n* decomp: read the hero through struct Hero in FUN_L00_002e4930\n\n* decomp: read the hero through struct Hero in FUN_L00_002e4fe8\n\n* decomp: read the hero through struct Hero in FUN_L06_00222fb8\n\n* decomp: read the hero through struct Hero in FUN_L11_0023c7a0\n\n* decomp: read the hero through struct Hero in FUN_L15_002044c8\n\n* decomp: read the hero through struct Hero in FUN_L17_002e8e08\n\n* decomp: read the hero through struct Hero in FUN_L18_00213b40\n\n* decomp: read the hero through struct Hero in both hero_set_state\ncopies\n\n* decomp: read the hero through struct Hero in FUN_L05_00329358\n\n* decomp: read the hero through struct Hero in FUN_L05_00253850\n\nAdds the six pose flags at 0x6E0 and their counter at 0x6F8.\n\n* decomp: read the hero through struct Hero in FUN_L17_002eea70\n\n* decomp: read the hero through struct Hero in FUN_L00_00298b18\n\n* decomp: read the hero through struct Hero in FUN_L02_002dbd38\n\n* decomp: compare the hero ground moby without pointer warnings\n\n* decomp: read the hero through struct Hero in FUN_L01_002b9eb0\n\n* decomp: read the hero through struct Hero in FUN_L00_00257470\n\n* decomp: read the hero through struct Hero in FUN_L00_002167d0\n\n0x3B4 becomes a float/int union: it is written as a float and zeroed as\nan int.\n\n* decomp: read the hero through struct Hero in FUN_L00_00209638 and\nFUN_L00_00209848\n\nAdds the three counters at 0x904..0x908 and the short at 0x1EB0.\n\n* decomp: read the hero through struct Hero in FUN_L00_00208820 and\nFUN_L00_00208a10\n\n* decomp: read the hero through struct Hero in FUN_L00_00206080\n\n* decomp: read the hero through struct Hero in FUN_L00_0020b5b8\n\n* decomp: read the hero through struct Hero in FUN_L00_00207a58\n\n* decomp: read the hero through struct Hero in FUN_L00_002323b8\n\n* decomp: read the hero through struct Hero in six more level files\n\n* decomp: read the hero through struct Hero where code cast &hero to\nbytes\n\n* decomp: read the hero through struct Hero instead of raw hero\naddresses\n\nByte views of D_0013F350 and of addresses inside the hero (such as\nD_0013F3D0, the position) now use struct Hero fields.\n\n* decomp: read the hero through struct Hero in more hero-address uses\n\n* decomp: name more hero fields in the help unit\n\n* decomp: read the hero through struct Hero in more local hero pointers\n\n* decomp: read the hero through struct Hero where local views were cast\nonto it\n\n* decomp: read the hero through struct Hero in place of hero-address\naliases\n\n* decomp: name more hero fields and read them through struct Hero\n\n* decomp: read the hero through struct Hero in FUN_L00_00229660\n\n* decomp: read the hero through struct Hero in two hero_set_state copies\nand FUN_L01_00232978\n\n* decomp: read the hero through struct Hero in FUN_L11_00313290","measures":{"fuzzy_match_percent":71.21571,"total_code":3547428,"matched_code":2469892,"matched_code_percent":69.62486,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3573,"matched_functions_percent":84.32854,"complete_code":2469892,"complete_code_percent":69.62486,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":338}},{"timestamp":"2026-10-10T05:33:49Z","commit_sha":"97214fd075d533235bd59417d6d3a2a1ba27ded7","commit_message":"decomp: read the hero through struct Hero in the remaining level functions (#140)\n\n* decomp: read the hero through struct Hero in FUN_L16_002e6208\n\n* decomp: read the hero through struct Hero in FUN_L00_002e4930\n\n* decomp: read the hero through struct Hero in FUN_L00_002e4fe8\n\n* decomp: read the hero through struct Hero in FUN_L06_00222fb8\n\n* decomp: read the hero through struct Hero in FUN_L11_0023c7a0\n\n* decomp: read the hero through struct Hero in FUN_L15_002044c8\n\n* decomp: read the hero through struct Hero in FUN_L17_002e8e08\n\n* decomp: read the hero through struct Hero in FUN_L18_00213b40\n\n* decomp: read the hero through struct Hero in both hero_set_state copies\n\n* decomp: read the hero through struct Hero in FUN_L05_00329358\n\n* decomp: read the hero through struct Hero in FUN_L05_00253850\n\nAdds the six pose flags at 0x6E0 and their counter at 0x6F8.\n\n* decomp: read the hero through struct Hero in FUN_L17_002eea70\n\n* decomp: read the hero through struct Hero in FUN_L00_00298b18\n\n* decomp: read the hero through struct Hero in FUN_L02_002dbd38\n\n* decomp: compare the hero ground moby without pointer warnings\n\n* decomp: read the hero through struct Hero in FUN_L01_002b9eb0\n\n* decomp: read the hero through struct Hero in FUN_L00_00257470\n\n* decomp: read the hero through struct Hero in FUN_L00_002167d0\n\n0x3B4 becomes a float/int union: it is written as a float and zeroed as an int.\n\n* decomp: read the hero through struct Hero in FUN_L00_00209638 and FUN_L00_00209848\n\nAdds the three counters at 0x904..0x908 and the short at 0x1EB0.\n\n* decomp: read the hero through struct Hero in FUN_L00_00208820 and FUN_L00_00208a10\n\n* decomp: read the hero through struct Hero in FUN_L00_00206080\n\n* decomp: read the hero through struct Hero in FUN_L00_0020b5b8\n\n* decomp: read the hero through struct Hero in FUN_L00_00207a58\n\n* decomp: read the hero through struct Hero in FUN_L00_002323b8\n\n* decomp: read the hero through struct Hero in six more level files\n\n* decomp: read the hero through struct Hero where code cast &hero to bytes\n\n* decomp: read the hero through struct Hero instead of raw hero addresses\n\nByte views of D_0013F350 and of addresses inside the hero (such as\nD_0013F3D0, the position) now use struct Hero fields.\n\n* decomp: read the hero through struct Hero in more hero-address uses\n\n* decomp: name more hero fields in the help unit\n\n* decomp: read the hero through struct Hero in more local hero pointers\n\n* decomp: read the hero through struct Hero where local views were cast onto it\n\n* decomp: read the hero through struct Hero in place of hero-address aliases\n\n* decomp: name more hero fields and read them through struct Hero\n\n* decomp: read the hero through struct Hero in FUN_L00_00229660\n\n* decomp: read the hero through struct Hero in two hero_set_state copies and FUN_L01_00232978\n\n* decomp: read the hero through struct Hero in FUN_L11_00313290\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>","measures":{"fuzzy_match_percent":71.21571,"total_code":3547428,"matched_code":2469892,"matched_code_percent":69.62486,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3573,"matched_functions_percent":84.32854,"complete_code":2469892,"complete_code_percent":69.62486,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":338}},{"timestamp":"2026-10-10T05:27:37Z","commit_sha":"8ceb14c514a064b5ac64d7f1618f594d11d21eba","commit_message":"overlay: 21 Pokitaru functions (#144)\n\n* overlay: pokitaru guard state change (692 B)\n\nFUN_L11_002d2088. Switch on moby->state, gp-relative scalars for the\nspeed and offset tables, and block-scoped temporaries in cases 8 and 10\nso the pair index is not if-converted into movz.\n\n* overlay: pokitaru target group proximity check (392 B)\n\nFUN_L11_002d2460. Indexing the target sets as a [set][4] array of\nshort pairs keeps the base pointer out of the load offset; the moby\naddress is written offset + list base.\n\n* overlay: pokitaru ring quad draw (740 B)\n\nFUN_L11_002f2d58. The uv table is the level symbol D_L11_001D3530, the\nradius is re-read from pvars instead of a temp (keeps the compare in its\nown register), and the corner pointer is taken per iteration.\n\n* overlay: pokitaru rotor spin and particle emit (812 B)\n\nFUN_L11_0030a500. The spawn loop is a counted up-loop (for k < n), which\nloop.c reverses into retail's countdown and which gives the j / j+1 split\nacross s0/s1; the particle lifetime is read into a local before the call.\n\n* overlay: pokitaru sentry update (1756 B)\n\nFUN_L11_002f0e40, the watcher routine of FUN_L11_002d0710 with a\ntime-trial usage record (stat 0x86) in state 1. Needed: the division\nwritten first in the record compare (so the reload follows the call),\nthe three flag stores in retail order, and the shared item/usage-stat\ndeclarations.\n\n* overlay: pokitaru escort state machine (3028 B)\n\nFUN_L11_002d14b0. Source case order 0-6, 12, 13, 7-11, 14, 15 follows\nretail's block order; a pvars struct and a path-point struct array let\nthe scheduler keep the table pointer like retail (char * offsets did not);\nthe leg != 0 gate index as a block-scoped int avoids movz.\n\n* overlay: pokitaru child moby grid layout (864 B)\n\nFUN_L11_0030dd18. Indexing the children as grid[row][col] (not a walking pointer) keeps row live through the row prologue, which fixes the order of the hoisted row tests.\n\n* overlay: pokitaru path moby hit handling (1080 B)\n\nFUN_L11_00310698. D_001413D0 needs section(\".data\") (NOT_SDA) for retail's split lui/lw pair; the hit-info vector is copied as a u128 and the second state's stores are ordered 0x80, 0x88/0x8C, 0xC0/0xC4.\n\n* overlay: pokitaru path moby update (1304 B)\n\nFUN_L11_00310180. Each turn case takes its own block-scoped pointer to rot.z, so the pointer is a block-local pseudo and moby/pvars land in s1/s2 as in retail.\n\n* overlay: pokitaru tile row and light setup (1540 B)\n\nFUN_L11_0030e088. FUN_L01_002b7c68 takes two args (as in L13); the spark\ncall takes a row pointer computed once, and the spawn counter is written as\na load plus a separate increment instead of a post-increment.\n\n* overlay: pokitaru grid spawner and camera blend (1300 B)\n\nFUN_L11_0030d800. The level tables are int-typed so the row offset can come\nfirst in the sum, the case 2 pointers are block-scoped, and the first child\npos copy uses qcopy_nc so the slot pointer is not reloaded.\n\n* overlay: pokitaru moby set controller (2600 B)\n\nFUN_L11_0030c788. The 0x161Fxx moby tables are MACRO_ADDR (one-register la),\nthe case 2 loops use a block-scoped counter, D_L11_0015F3FC is a plain extern\n(also in FUN_L11_0030d800) so only delay-slot stores become gp-relative, and\nthe final 1.0f stores are written in address order.\n\n* overlay: pokitaru moby set layout (1612 B)\n\nFUN_L11_0030d1b0. Each of the four loops has its own counter and block-scoped\ntemporaries, the 0x161Fxx tables are MACRO_ADDR, two of the 16-byte copies\nare qcopy_nc, and the signs are written as `cond ? 1 : -1` with the\ncomparison the movz tests.\n\n* overlay: pokitaru ship flight update (2648 B)\n\nFUN_L11_00312838, the Pokitaru copy of FUN_L17_002ec360 (no path steering, a\ncamera preset toggle and a usage counter). D_L11_0015F580 has to be declared\nMACRO_ADDR at the top of the file: declared next to the function, the\nsection attribute is not honoured and the address is split.\n\n* overlay: pokitaru ship moby update (3276 B)\n\nFUN_L11_00313290, the Pokitaru copy of FUN_L17_002ed018. The ldl/ldr/sdl/sdr\nloop is the compiler's copy of a 0x400-byte struct (the health bar palette\nsaved to D_L11_001F1088). The saved flag D_L11_00162170 needs its own sda\ndeclaration (as a field of hp_bar_palette it is reached with lui), and\nD_00141C10 is help_stats[0x55].count. The ship vars struct gains the\nfields this function uses.\n\n* overlay: pokitaru chain link damage (952 B)\n\nFUN_L11_00317c98. Reads the chain mobys' private variables through a\nfile-local struct; the two copy loops after the calls need their own\nblock-scoped counters so they stay in caller-saved registers.\n\n* overlay: pokitaru two-door gate (1444 B)\n\nFUN_L11_00316320. qcopy.h now comes before it so the copies inline, and\nthe file includes the shared hero header for hero.moby / hero.motion.pos.\nSeparate locals for the pos and rot copy targets of each door give\nretail's register choice.\n\n* overlay: pokitaru chain head update (948 B)\n\nFUN_L11_003172c0. FUN_0020c4f8 takes only the class here; each case\ngets its own block-scoped loop counter, the link copies go through a\nlocal, and D_001413D4 is read as an array element, which gives retail's\nregisters for the compare.\n\n* overlay: pokitaru chain link follow (1144 B)\n\nFUN_L11_00317820. The distance call is written twice around the search\nloop (retail cross-jumps the two calls), call arguments take &pts[i]\nfrom a path struct, and the coordinate loads go through row pointers\n(path + i * 16) so the path base comes first in each addu.\n\n* overlay: pokitaru path patroller update (1520 B)\n\nFUN_L11_00315968. Its pvars go through a file-local struct (field stores\nthen do not force reloads of frame_time), the hit position is copied as\na u128 member, the two reach stores are cross-jumped into one, and the\nD_L11_001B0EB0 alias is shared with FUN_L11_003172c0. qcopy.h moves to\nthe top of the file.\n\n* overlay: name the pokitaru chain link catch-up offset\n\nL11ChainVars 0xC0 is the distance a link trails its slot by after a link is destroyed; the head update eases it to 0. No code change.\n\n* overlay: pokitaru ship pickup (1648 B)\n\nFUN_L11_0030f728. Declaring the ship pointer before the pvars pointer gives retail's $20/$21 assignment (local-alloc order).","measures":{"fuzzy_match_percent":71.21571,"total_code":3547428,"matched_code":2469892,"matched_code_percent":69.62486,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3573,"matched_functions_percent":84.32854,"complete_code":2469892,"complete_code_percent":69.62486,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":338}},{"timestamp":"2026-10-10T05:26:41Z","commit_sha":"a553e2ec8069d055ea9616573bd8b6f430b20486","commit_message":"overlay: finish Kerwan (#143)\n\n* overlay: kerwan patrol enemy update (3688 B)\n\nFUN_L03_002c5bb8. The death state repeats the remove-and-return tail instead of\njumping to the shared one, as in the matched Fleet copy (FUN_L17_002eeb68).\n\n* overlay: kerwan guide npc update (2104 B)\n\nFUN_L03_002db558. The save call (FUN_0020b178) is declared returning int so\nlocal-alloc puts the final warp index in $3; the first reward record reads the\ngroup byte into a block-local int, the second uses da870's goto + do/while (0).\n\n* overlay: kerwan train pull update (1152 B)\n\nFUN_L03_00292890. A no-op `if (next_id != 0) data->iA0 = next_id;` keeps a label\nat the then-block start through reload, so `coupling` is reloaded instead of\ninheriting $4; reload_cse and jump2 then delete the store and branch.","measures":{"fuzzy_match_percent":70.33338,"total_code":3547428,"matched_code":2438592,"matched_code_percent":68.74254,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3552,"matched_functions_percent":83.8329,"complete_code":2438592,"complete_code_percent":68.74254,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":338}},{"timestamp":"2026-10-10T03:40:46Z","commit_sha":"cdddf69e53a2a227d5b64b0e64cffd24fda66e0c","commit_message":"overlay: three Kerwan functions (#142)","measures":{"fuzzy_match_percent":70.137634,"total_code":3547428,"matched_code":2431648,"matched_code_percent":68.54679,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3549,"matched_functions_percent":83.76209,"complete_code":2431648,"complete_code_percent":68.54679,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":336}},{"timestamp":"2026-10-09T22:23:42Z","commit_sha":"36a18ca4459480f7080e33f2ec413ef8485250e5","commit_message":"decomp: clean up recently matched functions (names, structs, callees) (#141)","measures":{"fuzzy_match_percent":70.00266,"total_code":3547428,"matched_code":2426860,"matched_code_percent":68.41182,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3546,"matched_functions_percent":83.69129,"complete_code":2426860,"complete_code_percent":68.41182,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":336}},{"timestamp":"2026-10-09T21:48:02Z","commit_sha":"80a82c801401e0b71cbd4b63c9c3f2f771522124","commit_message":"decomp: decompilerizer batch 8 (#139)\n\n* decomp: improve cmd_sem_init\n\n* decomp: improve update_visible_resident_objects\n\n* decomp: improve LoadDefaultMpegQuantizerMatrix\n\n* decomp: improve append_fullscreen_setup_strips\n\n* decomp: improve sceGsSetDefLoadImage\n\n* decomp: improve build_indexed_resident_render_packet\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve draw_level_selection_map\n\n* decomp: improve transition_do_transition\n\n* decomp: improve update_menu_grid_selection\n\n* decomp: improve FUN_00120558\n\n* decomp: improve update_visible_resident_objects\n\n* decomp: improve LoadDefaultMpegQuantizerMatrix\n\n* decomp: improve sceGsSetDefLoadImage\n\n* decomp: improve FUN_0022abc0\n\n* decomp: improve memcard_restore_data\n\n* decomp: improve sceCdInit\n\n* decomp: improve set_pal_mode\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve _getRef0\n\n* decomp: improve set_pal_mode\n\n* decomp: improve fast_decompress\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve fast_decompress\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve sound_update\n\n* decomp: improve FUN_00120558\n\n* decomp: improve FUN_L00_00210748\n\n* decomp: improve FUN_L00_00261968\n\n* decomp: improve FUN_L00_001fc558\n\n* decomp: improve FUN_L00_00236268\n\n* decomp: improve FUN_L00_00206c08\n\n* decomp: improve FUN_L00_0025b6b8\n\n* decomp: improve FUN_L00_0024f0e8\n\n* decomp: improve FUN_L00_00235668\n\n* decomp: improve FUN_L00_00284d90\n\n* decomp: improve FUN_L00_00264740\n\n* decomp: improve FUN_L00_002bcf98\n\n* decomp: improve FUN_L00_00249d80\n\n* decomp: improve FUN_L01_002ef350\n\n* decomp: improve FUN_L00_002599e8\n\n* decomp: improve FUN_L00_0024f440\n\n* decomp: improve FUN_L00_002df808\n\n* decomp: improve FUN_L00_00241788\n\n* decomp: improve FUN_L00_00285008\n\n* decomp: improve FUN_L00_002468b8\n\n* decomp: improve FUN_L00_00211670\n\n* decomp: improve FUN_L01_002ef560\n\n* decomp: improve FUN_L00_002076a8\n\n* decomp: improve FUN_L01_00302438\n\n* decomp: improve FUN_L00_00261b48\n\n* decomp: improve FUN_L00_00227778\n\n* decomp: improve FUN_L00_0025d808\n\n* decomp: improve FUN_L01_00315de0\n\n* decomp: improve FUN_L00_001f3770\n\n* decomp: improve FUN_L00_002995d0\n\n* decomp: improve FUN_L00_002648e0\n\n* decomp: improve FUN_L01_00234358\n\n* decomp: improve FUN_L00_00237840\n\n* decomp: improve FUN_L00_002cbcc0\n\n* decomp: improve FUN_L01_0028bb90\n\n* decomp: improve FUN_L00_002ebbd8\n\n* decomp: improve initialize_level_graphics_frame_effect_state\n\n* decomp: improve FUN_L05_0029bbe0\n\n* decomp: improve FUN_L08_002d6450\n\n* decomp: improve FUN_L05_003166a0\n\n* decomp: improve FUN_L03_002e8628\n\n* decomp: improve FUN_L14_002f1040\n\n* decomp: improve FUN_L14_002de1f8\n\n* decomp: improve FUN_L02_002fb648\n\n* decomp: improve FUN_L12_003094a0\n\n* decomp: improve update_hoverboard_girl_boobs_animation\n\n* decomp: improve FUN_L07_0029b8d8\n\n* decomp: improve FUN_L11_003180a0\n\n* decomp: improve FUN_L00_002738e8\n\n* decomp: improve FUN_L14_003039e0\n\n* decomp: improve FUN_L09_00305a28\n\n* decomp: improve FUN_L11_002d2460\n\n* decomp: improve FUN_L06_002ff100\n\n* decomp: improve spawn_class_1b3_projectile\n\n* decomp: improve FUN_L06_002e9b60\n\n* decomp: improve FUN_L05_0030f408\n\n* decomp: improve draw_projected_fading_quad\n\n* decomp: improve FUN_L04_002d1418\n\n* decomp: improve FUN_L09_002efe48\n\n* decomp: improve FUN_L00_002831c0\n\n* decomp: improve FUN_L07_00311eb8\n\n* decomp: improve FUN_L05_002f4f60\n\n* decomp: improve draw_nine_transformed_copies\n\n* decomp: improve FUN_L14_002eef60\n\n* decomp: improve FUN_L01_002b7a48\n\n* decomp: improve FUN_L00_002be650\n\n* decomp: improve FUN_L14_002e0170\n\n* decomp: improve FUN_L15_002a29b8\n\n* decomp: improve FUN_L11_0030eb90\n\n* decomp: improve FUN_L13_002e97e0\n\n* decomp: improve FUN_L09_0030a778\n\n* decomp: improve FUN_L12_00306350\n\n* decomp: improve FUN_L05_00254358\n\n* decomp: improve FUN_L06_002fd1a0\n\n* decomp: improve FUN_L08_002e2250\n\n* decomp: improve FUN_L08_00316fa8\n\n* decomp: improve FUN_L14_00301de8\n\n* decomp: improve FUN_L01_002c7530\n\n* decomp: improve FUN_L00_0020cd08\n\n* decomp: improve FUN_L00_0029ad08\n\n* decomp: improve FUN_L00_00261d78\n\n* decomp: improve FUN_L14_002eb568\n\n* decomp: improve FUN_L00_002c35c0\n\n* decomp: improve FUN_L05_00304058\n\n* decomp: improve FUN_L00_00221310\n\n* decomp: improve FUN_L14_002b5968\n\n* decomp: improve FUN_L00_002bed90\n\n* decomp: improve FUN_L00_00276908\n\n* decomp: improve FUN_L00_00275aa0\n\n* decomp: improve FUN_L04_002923b8\n\n* decomp: improve FUN_L00_002637f8\n\n* decomp: improve FUN_L12_00306828\n\n* decomp: improve FUN_L10_002e5be0\n\n* decomp: improve FUN_L00_0026b230\n\n* decomp: improve FUN_L06_002fd460\n\n* decomp: improve FUN_L08_002e9758\n\n* decomp: improve FUN_L14_00305758\n\n* decomp: improve FUN_L10_002ea1f0\n\n* decomp: improve FUN_L00_001fcca0\n\n* decomp: improve draw_radial_quad_strip\n\n* decomp: improve FUN_L01_002b8f98\n\n* decomp: improve FUN_L00_002092c8\n\n* decomp: improve draw_moby_radius_ring\n\n* decomp: improve FUN_L00_0029a400\n\n* decomp: improve FUN_L14_002fc0f0\n\n* decomp: improve FUN_L15_002bddb0\n\n* decomp: improve FUN_L06_002f2910\n\n* decomp: improve FUN_L05_00254058\n\n* decomp: improve FUN_L13_002cecb8\n\n* decomp: improve FUN_L11_0031a438\n\n* decomp: improve FUN_L18_002f9780\n\n* fix: use shared globals after main rebase\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":70.00266,"total_code":3547428,"matched_code":2426860,"matched_code_percent":68.41182,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3546,"matched_functions_percent":83.69129,"complete_code":2426860,"complete_code_percent":68.41182,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":336}},{"timestamp":"2026-10-09T21:09:54Z","commit_sha":"1133b867f763ecbf27c412ad35cf6c81b563805b","commit_message":"decomp: read the hero through struct Hero in more level functions (#138)\n\n* decomp: FUN_L00_00233ee8 reads the hero through struct Hero\n\n* decomp: FUN_L00_00231e78 reads the hero through struct Hero\n\n* decomp: FUN_L06_00227cf8 reads the hero through struct Hero\n\n* decomp: FUN_L00_00232fe8 reads the hero through struct Hero\n\n* decomp: FUN_L00_002330d0 reads the hero through struct Hero\n\n* decomp: expand the byte-offset hero macros in four level files\n\n* decomp: FUN_L00_002279b0 reads the hero through struct Hero\n\n* decomp: FUN_L05_002515d0 reads the hero through struct Hero\n\n* decomp: FUN_L00_00229910 reads the hero through struct Hero\n\nAlso drops the parentheses the expanded macros left around field reads.\n\n* decomp: FUN_L00_002da250 reads the hero through struct Hero\n\n* decomp: FUN_L00_002df1e0 reads the hero through struct Hero\n\n* decomp: FUN_L00_002ce1f0 and FUN_L00_001f4490 read the hero through struct Hero\n\nBoth kept a local view type for a pointer already set to &hero; the\npointers are struct Hero * now. struct Hero gains the six moby slots at\n0x2020.\n\n* decomp: type four hero pointers as struct Hero","measures":{"fuzzy_match_percent":69.820274,"total_code":3547428,"matched_code":2419796,"matched_code_percent":68.212685,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3533,"matched_functions_percent":83.38447,"complete_code":2419796,"complete_code_percent":68.212685,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":334}},{"timestamp":"2026-10-09T21:00:04Z","commit_sha":"c799cb0b7f953e1dfaa0dd26e9b3b18d7b890b7c","commit_message":"decomp: get_effect_texture matches (#137)\n\nget_effect_texture hands out the TEX0 of a built-in effect texture (the\nfont textures among them) and, the first time, reserves its GS memory and\nqueues its upload. It matches once width_log2 is reused for the area\nexponent and tex0 is tested through the array before the entry pointer\nis taken.","measures":{"fuzzy_match_percent":69.820274,"total_code":3547428,"matched_code":2419796,"matched_code_percent":68.212685,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3533,"matched_functions_percent":83.38447,"complete_code":2419796,"complete_code_percent":68.212685,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":334}},{"timestamp":"2026-10-09T20:37:09Z","commit_sha":"9a7b3902b2581cf2d827dbd66eeed14056a18d6d","commit_message":"decomp: struct Hero and shared globals in level code (#136)\n\n* decomp: one declaration for the frame timing and bolt globals\n\nName the frame timing set by set_video_timing (frame_time, frame_scale and\ntheir powers) and the bolt count in rnc/globals.h. Level and boot files\ninclude it instead of redeclaring the D_ symbols; declarations that change\nthe emitted code (MACRO_ADDR, sda, NOT_SDA, aliases kept for reloads) stay\nlocal.\n\n* decomp: read the hero through struct Hero in level code\n\nLevel files that walked the player character as a byte array now use\nstruct Hero fields, through hero or a local struct Hero pointer. Fields\nthese reads need are added to struct Hero in place of padding. Copies\nthat need their own placement (section .data) stay local, typed as\nstruct Hero.\n\n* decomp: struct Hero in the remaining level hero files\n\nThe same field rewrite for the files where some functions need the byte\nview to stay exact: those functions keep it, the rest use struct Hero.\n\n* decomp: replace local hero struct views with struct Hero\n\nLevel files that declared their own partial struct over the hero now\nread the same fields through struct Hero.\n\n* decomp: name the hero's ground probe fields\n\nThe probe that sets hero.unk2A0..unk2FC (FUN_L00_00226f10 and its level\ncopies) copies the hit point, its z, the distance from motion.pos and the\nhit moby into them: ground_point, ground_z, ground_distance and\nground_moby. unk30E is cleared on landing and compared with\nscale_game_frames(n) elsewhere: air_frames. Layout checks cover the\nfields added for the level views.\n\n* decomp: one declaration for depth_buffer_address\n\nD_0015EE88 goes into GS ZBUF_1 shifted by 13 (the ZBP field), the name\ntwo files already used; it now lives in rnc/globals.h.","measures":{"fuzzy_match_percent":69.81636,"total_code":3547428,"matched_code":2419468,"matched_code_percent":68.203445,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3532,"matched_functions_percent":83.36087,"complete_code":2419468,"complete_code_percent":68.203445,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":333}},{"timestamp":"2026-10-09T18:41:03Z","commit_sha":"5a199f1e58d842ce81f32b5ec2f29120780079dd","commit_message":"decomp: one type per global, data defined in its unit (#135)\n\n* chore: scan the boot code for the data it reads\n\nscripts/data-refs.py disassembles the boot ELF and lists every data\naddress that loads or stores touch, with the section, widths and the\nunit that makes the access. It reads config/us/SCUS_971.99 and writes\nbuild/data-refs/, which is ignored, so no game-derived output is\ncommitted.\n\ncapstone is added to requirements.txt and installed in the checks job\nfor the new tests.\n\n* chore: scan a level program for the data it reads\n\ndata-refs.py --level N reads a level's records from the Tools checkout's\nextracted/overlays and lists the data its code touches, owner by the\nnearest function in config/overlays/us/functions.tsv. A level also sees\nthe executable's core.* data. Output stays in build/data-refs/level-NN/.\n\n* chore: catalogue the boot and level data by origin\n\ndata-refs.py --catalog writes config/us/data.yaml and\nconfig/overlays/us/data/level-NN.yaml: every data address the code\ntouches, grouped by section and by the subsystem that uses it, with\nname, type, access counts and users. A rerun keeps hand-edited names,\ntypes and notes.\n\n* decomp: own the RPC collision message in snd_send_iop_command_and_wait\n\n* config: keep the fixed-address symbols in symbols.yaml\n\nThe baseline build writes the three files splat reads from it, so\nsymbol_addrs.txt, undefined_syms.txt and undefined_funcs_auto.txt are\ngone from the repository.\n\n* config: keep the data symbols in data.yaml\n\nsymbols.yaml now lists only functions; the data symbols the build pins\nsit in the fixed block of data.yaml, which a catalogue rerun keeps.\n\n* decomp: own the messages of three audio and image functions\n\nsnd_bank_load_by_loc, snd_send_iop_command_no_wait and\njump_to_image_setup now hold their strings as literals; the .rodata\noverlay places them at the retail address.\n\n* decomp: define the vsync counters in count_vsync\n\nDefined below their only user, the assembler does not know their size at\nthe use, so the code reaches them with lui like retail does.\n\n* decomp: define the video timing and debug font variables in their units\n\n* decomp: define the archive buffers and the subtitle flag in their units\n\n* decomp: define the camera, pause and moby counters in their units\n\n* chore: name the struct fields in the data catalogue\n\nAddresses inside a declared struct object are listed as object.field,\nwith the layout read from the headers.\n\n* config: rename symbols.yaml to functions.yaml and describe lists by purpose\n\n* config: pin every fixed symbol in pinned.yaml; keep level catalogues out of the repo\n\ndata.yaml is now only the generated data catalogue. Level catalogues are\nwritten to build/data-refs/level-NN/ on request.\n\n* decomp: place typed data from src/data/ at its retail address\n\nData with no proven owning unit lives in src/data/<section>/<ADDR>_<name>.c;\nthe first is music_stream_state.\n\n* chore: data-refs.py --emit writes typed src/data/ files from the headers\n\nDefines hero, voice_pool, disc_table, draw_config, view_context, hud_state,\nmenu_system and fs_aa_buffer at their retail addresses.\n\n* chore: data-refs.py --emit fills arrays of structs; define memory_card_state\n\n* decomp: define font palette, camera flag, texture uploads and material templates in src/data\n\ndata-refs.py --emit now fills top-level scalars and arrays.\n\n* decomp: define map state, gadget animations, preview manipulators and billboards in src/data\n\n* decomp: define resident class tables and panel slot flags in src/data\n\n* decomp: define preview, graphics setup and render class tables in src/data\n\n* decomp: define font, map, vendor, label and effect tables in src/data\n\n* decomp: define runtime and SDK state words from src/data; --emit handles scalars\n\n* decomp: define item flags, pad state, sound work, draw environment and sprite queue from src/data\n\n* decomp: use header declarations for core words, FS state, IPU table, ROM name, sound read work and font metrics\n\n* decomp: use controller_state and item flag headers instead of local externs in boot code\n\n* decomp: use graphics buffer, draw state, fs_aa_buffer, music stream and camera headers instead of local externs\n\n* decomp: use memory card and view context headers in save list, fog, font queue and space transition\n\n* decomp: define camera saved states and the image clear buffer from src/data; hud bank users read hud_state\n\n* decomp: define panel slots, class tables, label entries and vendor timers from src/data\n\n* decomp: define libgraph params, DMA channels, AA packets, level flags from src/data; pad state views\n\n* decomp: define screen extent from src/data; hero state views replace stray labels\n\n* decomp: help state reads controller_state.pressed\n\n* decomp: one LevelRenderState type for D_0013E030 in boot code\n\n* decomp: DATA_AT places each data object; single-user data moves into its user's file\n\n* decomp: shared data grouped in src/data/<topic>.c; --emit appends to topic or user file\n\n* docs: data definitions in CONTRIBUTING; raw byte blobs back to assembly\n\n* decomp: fold single-use data headers into their file; controller_state leaves pinned\n\n* decomp: startlevel reads level_render_state\n\n* overlay: read screen_extent instead of D_0013E500\n\n* config: tools check installs PyYAML for the symbol and data yaml\n\n* config: keep splat's symbol_addrs.txt and undefined_*.txt instead of pinned.yaml\n\n* config: data catalogue is generated into build/, names and types live in headers\n\n* decomp: data follows splat convention; DATA_OVERLAYS replaces DATA_AT, shared data back in assembly\n\n* decomp: data catalogue drops hand-edit support and PyYAML; names come from headers\n\n* config: tools check installs capstone and pyelftools for data-refs.py","measures":{"fuzzy_match_percent":69.81636,"total_code":3547428,"matched_code":2419468,"matched_code_percent":68.203445,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3532,"matched_functions_percent":83.36087,"complete_code":2419468,"complete_code_percent":68.203445,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":333}},{"timestamp":"2026-10-09T17:29:04Z","commit_sha":"f5535eedd4ed5554dbced3e064b5bd66931f7314","commit_message":"overlay: hero movement helpers (dust, gadget throw, auto-aim) (#134)\n\n* overlay: hero dust burst, gadget throw and auto-aim target pick\n\nFUN_L00_00209ca8 spawns the landing dust: a flash at the hero's feet, puffs\naround it and debris chunks thrown outward with random colour and life.\n\nFUN_L00_00217658 launches a thrown gadget along the hero's aim\n(hero.aim_yaw/aim_pitch, new names for 0xA74/0xA78) and fills its pvars.\n\nFUN_L00_002630c8 picks the auto-aim target: the closest moby of class\ncategory 5 inside max_angle of the shot with a clear line of sight, or any\nsuch moby within 7.5 units and 60 degrees of the hero's facing. The aim\npoint is the moby position raised by its bound height (0.5 without one).\n\nstruct Hero gains the seven item slots, the three easing records at 0x18F0\n(struct HeroEase) and the fields these and the movement code read; layout\nchecks cover them.\n\n* fix: build l02 002400c8.c past the GNU as relaxation assert\n\nGNU as asserts (tc-mips.c:11454) on FUN_L02_002dcb38: a relaxable load sits\nin a noreorder delay slot and an unsized symbol is loaded with `la` later in\nthe same frag. Both places that run GNU as on overlay code never compare its\n.text: the obj/ compile check now assembles with -G0, and the data-size\nreference for padless finish reads a copy without `.set noreorder` and\n`.set nomacro`. Reference data section sizes are unchanged on every unit.\n\n* decomp: mark five boot math helpers as intentional asm\n\nclear_u64_value, convert_integer_to_float and the add, subtract and\ndifference rotation helpers do things the compilers never emit: a direct\n`sq $0` store, mtc1 without the assembler's hazard nop, a compare reused\nfrom a branch delay slot, -pi built in $v0, and a hand-placed nop. None of\nthe three toolchains reproduces them from C. Each unit keeps its assembly\noracle and a comment with the reason in place of the C draft.\n\n* overlay: ease the hero's manipulator records (FUN_L00_00205168)\n\nEach record eases its rotation and position toward their targets, rebuilds\nthe quaternion, scale and translation it hands to its moby, and detaches\nonce everything has settled. struct HeroEase gets its full layout, with\nlayout checks; FUN_L00_002054e8 now calls it on the struct directly.","measures":{"fuzzy_match_percent":69.81636,"total_code":3547428,"matched_code":2419468,"matched_code_percent":68.203445,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4237,"matched_functions":3532,"matched_functions_percent":83.36087,"complete_code":2419468,"complete_code_percent":68.203445,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":333}},{"timestamp":"2026-10-09T13:59:45Z","commit_sha":"9228e395211cd4e56946ce3d1f5915f3191e7773","commit_message":"overlay: finish Aridia, five Novalis and two Eudora functions (#133)\n\n* overlay: aridia prop-carrying npc update (2728 B)\n\nFUN_L02_002e0dc0. The prop attach is a statement expression and the case-3 block sits in the switch so the stack slots overlap as in retail; usage record 50 is reached as D_00141968[14]; the dialogue camera spot (D_L02_0016CE60) is read through a .data alias of the file's WatcherReward type, and the game mode, frame delta and big-head flag through plain externs (macro loads).\n\n* overlay: aridia one-shot dust and spark burst (992 B)\n\nFUN_L02_002e0720. Each loop body is a statement expression so the two loops' temporaries share stack slots as in retail; the spark emitter's size float is declared before its int lifetime (same registers) to get retail's call order; D_0013D39D is a .data global (split %hi/%lo).\n\n* overlay: aridia dust puffs along a segment (580 B)\n\nFUN_L02_002d3a50. FUN_L00_0026d000 is declared in the argument order the other levels use (pos, three floats, n, vel, size, colour), which gives retail's call setup order; the particle pointer is taken inside the null check.\n\n* overlay: aridia smoke vent update (2516 B)\n\nFUN_L02_002ef020. Each burst and single-puff block has its own locals (shared ones shift the register allocation), and FUN_001f9bf8 is declared with its float first so the scale is evaluated before the vector addresses; reads struct Moby unkD0.\n\n* overlay: aridia lift update (4852 B)\n\nFUN_L02_002ddc88. The look-at block of state 5 and the node copies of\nstate 8 are written out in both branches (retail cross-jumps the\nidentical tails), which frees $fp for the &c PRE register.\n\n* overlay: aridia burrowing enemy update (6148 B)\n\nFUN_L02_002d3e50, the 30-state AI that brackets its update with EE timer 0\nreads. The PRE/cse shape of states 5/22 needs the clip-volume test written\nas `unk278 >= 0 && !inside` first; walk_188/18C are one chained store.\n\n* overlay: novalis debris burst on hit (992 B)\n\nFUN_L01_002f9810. When hit, spawns 200 smoke puffs and 40 debris chunks\n(FUN_L01_002f8530, called through an alias with its real argument order),\nthen removes itself. Loop 1's locals sit in a block of their own so loop 2\nreuses their stack slots, as retail does.\n\n* overlay: novalis lava blob update (1112 B)\n\nFUN_L01_0030ba18. Moves the blob with drag and gravity, spins it, drops a\ntrail of sparks and smoke, and on a hit or timeout splashes damage and\nremoves itself. The two particle spawners are called through aliases with\nthe argument order other levels' ports use.\n\n* overlay: novalis collectible debris burst (1152 B)\n\nFUN_L01_002fa800. Removed if already collected; when hit, bursts into 500\nsmoke puffs and 100 chunks, then sets its save bits and D_0013D388[0xE].\nSame shape as FUN_L01_002f9810; reuses its file-local vector types.\n\n* overlay: novalis water layer ripple and glow (524 B)\n\nFUN_L01_002feb58. On first use lowers and ripples the vertices of the four\nscrolling layers, then pulses their glow and queues FUN_L01_002feb28. The\nlayer fields are read as (D + i)->field: indexing D[i] folds the field\noffset into the base and loses retail's second copy of the address.\n\n* overlay: novalis rider carrier update (1756 B)\n\nFUN_L01_002f4960. Starts when the hero enters its clip volume, follows its\npath carrying up to eight rider mobys and steering its camera moby, drops\nthe riders at the first marked node and is removed near the path end.\nThe unit has its own file-local struct Moby, so moby.h cannot be included;\nthe function uses a file-local CarrierMoby with the shared layout.\n\n* overlay: eudora walker leg rig setup (500 B)\n\nFUN_L04_00295de8. Builds 002922d0.c with SN cc1 (OVERLAY_SN_UNITS): the\nplain C is exact under SN, the game compiler reverses the leg loop and merges\nits pointers; the neighbouring Eudora files 0024c4f0 and 0029eb20 are SN too,\nand the file's other C functions stay exact under SN.\n\n* overlay: share the eudora walker leg rig layout\n\nMoves the rig types of FUN_L04_00295de8 into include/rnc/overlay/leg_rig.h for the other rig functions (FUN_L04_002923b8, FUN_L04_002d1418).\n\n* overlay: eudora moby engine voice update (492 B)\n\nFUN_L04_002c1b80. The voice-playing check takes the moby as a long\n(FUN_L00_0028d8c0): as a pointer argument the compiler reuses $a0 instead\nof copying the moby back from $s0 as retail does.","measures":{"fuzzy_match_percent":69.72615,"total_code":3547652,"matched_code":2416312,"matched_code_percent":68.110176,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4242,"matched_functions":3528,"matched_functions_percent":83.16832,"complete_code":2416312,"complete_code_percent":68.110176,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":333}},{"timestamp":"2026-10-09T08:01:02Z","commit_sha":"9a455b48e944dc93bb83b85adcfc098595e5b09e","commit_message":"overlay: ten kerwan and aridia functions (#132)\n\n* overlay: kerwan path mover spawn (228 B)\n\nFUN_L03_002db198. Spawns a class 0x382 mover on a rail path; uses the\nstruct Moby fields already named upstream (no header change).\n\n* overlay: kerwan rail taxi update (1916 B)\n\nFUN_L03_002d3198. Five-route rail taxi: waits for the hero in a route's\ntrigger volume, flies out, drops the hero, then flies back or onward.\n\n* overlay: kerwan trooper update (2380 B)\n\nFUN_L03_002c9eb8. Patrols its rail path, turns to the target from\nFUN_L03_0024e830, fires three-shot bursts and blows up when shot down or\nfallen. Names more of the file-local trooper pvars and the first field of\nRocketTarget (pads split, layout unchanged).\n\n* overlay: kerwan mine update (2432 B)\n\nFUN_L03_002cbea8. Same family as the L00 mine FUN_L00_002aa670: falls,\nsticks to or homes on its target, arms, then explodes into debris with camera\nshake (or shrinks away when old). The 0x50-byte blast record is copied from\nD_L03_001E32B0.\n\n* overlay: kerwan vendor camera init (372 B)\n\nFUN_L03_002eb978. The timer store is written as an indexed int access so\ngcc sees an in-struct store that cannot alias the D_L03_0015EF50 load,\nwhich lets the table load schedule ahead of the camera data stores.\n\n* overlay: aridia vendor camera mode set (132 B)\n\nFUN_L02_002f8a18: stores the mode in the camera moby; mode 3 re-aims from the hero position before the shared mode-2 path.\n\n* overlay: aridia lift platform update (1240 B)\n\nFUN_L02_002e2228. Names struct Moby rot (0x40), unk58, unk70, unkB0 and unkBC by splitting pads. The two allocate calls per branch are separate statements (retail cross-jumps their tails), and the mobys base is a plain extern so the assembler expands its load.\n\n* overlay: aridia enemy hit reaction (852 B)\n\nFUN_L02_002d85b8: file-local typed pvars struct (alias heuristics keep the float globals in registers); the knock-back vector address is taken in a block local before the atan2 call; store order per branch found by permutation runs.\n\n* overlay: aridia path enemy update (1168 B)\n\nFUN_L02_002d5c88: retail reads D_L02_0015FFD8 absolute in the respawn branch and gp-relative in the death branch; the sda alias is declared at block scope in the death branch (cc1 expands statements as it parses, so only later uses go through $gp). No pointer variables for the anim/target addresses (gcse reproduces retail's copies).\n\n* overlay: aridia spawned moby update (1188 B)\n\nFUN_L02_002dcb38: typed pvars and spawner structs; D_0014D590 indexed as [level][moby->b1][1] like shared/rendering/00250df8.c (level 2 constant); block-scope sda alias of D_L02_0015FFD8 for the gp-relative read in state 4.","measures":{"fuzzy_match_percent":69.039955,"total_code":3547652,"matched_code":2391968,"matched_code_percent":67.42397,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4242,"matched_functions":3515,"matched_functions_percent":82.861855,"complete_code":2391968,"complete_code_percent":67.42397,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":330}},{"timestamp":"2026-10-09T06:04:05Z","commit_sha":"3828c63f0971b56548f7eaebb896f1215bf01ee6","commit_message":"decomp: finish Kalebo III and Veldin Orbit, Kerwan train and vendor code (13 functions) (#131)","measures":{"fuzzy_match_percent":68.70429,"total_code":3547652,"matched_code":2380060,"matched_code_percent":67.08832,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4242,"matched_functions":3505,"matched_functions_percent":82.62612,"complete_code":2380060,"complete_code_percent":67.08832,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":329}},{"timestamp":"2026-10-09T06:01:56Z","commit_sha":"9a6fa9abd871a7031d964e57b880962418a2975f","commit_message":"decomp: promote four rendering and menu units (2404 B) (#130)","measures":{"fuzzy_match_percent":68.13592,"total_code":3547652,"matched_code":2358592,"matched_code_percent":66.483185,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4242,"matched_functions":3492,"matched_functions_percent":82.319664,"complete_code":2358592,"complete_code_percent":66.483185,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":326}},{"timestamp":"2026-10-09T04:36:45Z","commit_sha":"88c7892511b40b12b481b0812a018a27553f46cd","commit_message":"decomp: write about 180 more overlay and BOOT functions in C and type more moby fields (#129)\n\n* overlay: hero movement step FUN_L01_00233de0 and scene trigger FUN_L00_00266448 in C\n\nFUN_L01_00233de0 (1268 B, SN unit) moves the hero by its velocity and\nderives the frame's movement vectors; FUN_L00_00266448 (904 B, 14 levels)\nstarts a moby's scene when the hero comes close and faces it. Moby gets\nits rot vector at 0x40, Hero the gravity-frame argument at 0x4F8.\n\n* overlay: moby slider following a driver moby's progress FUN_L01_002f4710 in C\n\nSlides between two points by the driver's 0..1 progress and starts/stops its\nloop sound; the unit's Moby typedef gains bsphere/pos.\n\n* overlay: path that pushes the hero along it FUN_L01_002f3120 in C\n\nHero.unk22B8 (nearest carrying path distance) added to hero.h; the unit's\nMoby typedef moves above its first user.\n\n* overlay: explosion burst with particles, sound and light flash FUN_L01_002fa1b0 in C\n\nTakes struct Moby; the six-colour palettes and the flash light stay local.\n\n* overlay: draw the bolt counter HUD element FUN_L00_00239df8 in C\n\nPanel, spinning bolt icon, shadowed count and thousands separators\n(apostrophe, or a dot for languages 3 and 5) on the shared HudElem.\n\n* overlay: hero hit blink and gold weapon effect FUN_L01_00228e38 in C\n\nUses struct Hero (state, state_timer, moby, items[0]) instead of raw offsets.\n\n* overlay: falling effect particle update FUN_L00_00268d48 in C\n\nMoves by velocity plus drift, applies gravity and dies off the map or below\nthe cached ground height.\n\n* overlay: ledge probe FUN_L00_0020c758 in C\n\nAdds the shared circle_offset() inline (rnc/math/circle_offset.h) and\nCollisionHit.normal_z.\n\n* overlay: ledge probe FUN_L01_0022d838 in C\n\nSame probe as FUN_L00_0020c758 without the small-hero variant; shares\ncircle_offset() and CollisionHit.\n\n* overlay: hero lean values for state 2 FUN_L00_00215ef8 in C\n\nReads hero.items[3].moby2; Moby +0x2C becomes f32 scale.\n\n* fix: register_moby_class takes the class data block, not a Moby\n\nIts +0x2C word is a class field; Moby +0x2C is now f32 scale.\n\n* overlay: collect a bolt (CollectBolt) FUN_L00_002a6b70 in C\n\nAdds the bolt's value to the counters and its source's per-level stats,\nshows the bolt counter and spawns two sparkles; Moby gains unkB8.\n\n* overlay: spawn a class 0xb8 shot moby FUN_L04_002aee30 in C\n\nNamed vars block; Moby 0x30-0x33 become unk30/unk31/unk32.\n\n* config: drop dead and unneeded per-unit compiler flags\n\n__swrite now matches at the library's normal -O2 as the plain newlib\nshape (64-bit long write result truncated to int). The cmd_sem_init\nentry named a unit that is now an assembly wrapper.\n\n* config: build DIntr from its assembly, dropping its compiler flags\n\n* overlay: collectible pickup with cutscene FUN_L01_00307ca0 in C\n\nUses struct Hero instead of a local copy; Moby gains unk58 and unk70.\n\n* overlay: rise once the linked moby is collected FUN_L03_002dca30 in C\n\nTakes struct Moby; moby.h gains u16 unkB2 (lhu 0xB2 in the listing).\n\n* decomp: split out handle_menu_screen_buttons and write it in C\n\nGhidra missed the 0x88-byte leaf between FUN_002196b8 and fun_00219e10; it was part of a text gap blob.\n\n* decomp: sound options menu in C\n\n* overlay: vendor menu FUN_L00_0029c648 in C\n\nMenu state machine on D_L00_001CA4C0 (vendor_menu): open, browse\nlist/grid with sound and preview, close, and the exit cutscene.\nThe unit now takes Vec4 from rnc/math/vector.h, and the\nFUN_001f9cf8/FUN_001f9a10 prototypes take void pointers.\n\n* overlay: crate update FUN_L00_002cf218 in C\n\n* overlay: hero per-frame timers and ring check FUN_L00_002215c8 in C\n\n* overlay: spawn a child moby copying its parent's position and scale FUN_L13_002b4958 in C\n\n* overlay: scrolling textured ring band FUN_L00_002bdc50 in C\n\n* config: build 002bffa8 overlay unit with SN\n\n* overlay: predict a thrown moby's landing point FUN_L00_002c3af8 in C\n\nUses struct Hero, struct Moby and CollisionHit; hero.h gains unk670/unk674.\n\n* overlay: spawn a bolt moby FUN_L00_002a7438 in C\n\nTakes struct Moby; moby.h gains unk73 and the 0xC0 matrix rows.\n\n* overlay: oclass 0x25D tracker update FUN_L00_002d2ee8 in C\n\nBuilds with SN like the rest of its unit. Hero.unk2040 becomes the\ntracked moby pointer and PadState gains unk189; the unit's\nFUN_0020cca8, enqueue_callback_list_1 and FUN_001f9b80 prototypes take\nvoid pointers.\n\n* overlay: class 0xb8 shot update FUN_L04_002af058 in C\n\nReuses the unit's ShotVars; the collision probe block stays local.\n\n* config: mark fun_001f96f8 as intentional asm\n\nIts adda.s/madd.s accumulator sequence has no output template in any cc1 here\n(game, sdk, patched, SN 2.9/2.95), and C folds 0.25f+0.25f to a constant.\n\n* overlay: stick/pad slot select with hold counters and close FUN_L00_00237ba0 in C\n\n* decomp: mode_freeze_init in C\n\n* decomp: menu list entry update and actions fun_0021abf8 in C\n\nPause and main-menu list handler: highlight fade, back/cancel, entry actions,\nup/down selection. The entry count loop goes before reading selected/flags.\n\n* config: mark FUN_L00_00250320 as intentional asm\n\nIt uses $at as a plain register (dsrl32/andi/sw), which no cc1 allocates.\n\n* decomp: load_pif_as_psmt8_h in C\n\nThe CBP/TCC part of TEX0 is built in its own temporary, as retail's registers show.\n\n* overlay: l07 launch parameters FUN_L07_0030e858 in c\n\n* overlay: l09 vendor damage handler FUN_L09_00303b30 in c\n\n* overlay: l09 path next-point FUN_L09_00294ae0 in c\n\n* overlay: l09 vendor hit handler FUN_L09_00303fc8 in c\n\n* overlay: l07 swing gate state machine FUN_L07_0031b3f0 in c\n\n* overlay: l03 hero grab-spot search FUN_L03_00205830 in c\n\n* overlay: l03 rail path spawner update FUN_L03_002db280 in c\n\n* overlay: hud timer FUN_L05_00266710 in c\n\n* decomp: render_environment_mapped_object and append_rotated_sprite_quad in C\n\n* overlay: l15 hero per-frame upkeep FUN_L15_00215e58 in c\n\n* overlay: l07 walker heading pick FUN_L07_0030eee8 in c\n\n* overlay: l04 warp portal update FUN_L04_002e1a10 in c\n\n* overlay: l08 path-following gunship update FUN_L08_002e9b70 in c\n\n* overlay: l01 hero per-frame update FUN_L01_0023c710 in c\n\n* overlay: l06 hero per-frame update FUN_L06_002348d0 in c\n\n* overlay: trigger moby that runs its lists on enter and leave FUN_L05_002f5200 in C\n\n* overlay: area moby that tracks the nearest one to the hero FUN_L01_002f2eb8 in C\n\n* overlay: shop item moby that sells once and charges bolts FUN_L01_002e1ac0 in C\n\n* overlay: debris spawner with random spin and lifetime FUN_L01_002f8530 in C\n\n* overlay: path points no segment reaches as a bit mask FUN_L01_00276a48 in C\n\n* overlay: projectile spawner with two trails FUN_L09_00307ba8 in C\n\n* overlay: l02 single particle puff FUN_L02_002d5a68 in c\n\n* overlay: l08 two-path gunship update FUN_L08_002e8cd0 in c\n\n* overlay: pooled child spawner FUN_L03_002bec60 in c\n\n* overlay: l13 beam quad strip draw FUN_L13_003098d0 in c\n\nDraws 15 textured quads along the moby's point list, twice each with the\nodd corners pulled in and then raised.\n\n* overlay: l05 sliding pose-table moby update FUN_L05_0030e508 in c\n\nPlaces the moby from its pose entry, waits for its trigger, eases it to the\nend point and lowers it; the speed scale is computed before pos = 0.\n\n* overlay: l05 lift update FUN_L05_003156d0 in c\n\n* overlay: l02 hero movement step FUN_L02_002226d8 in c\n\n* overlay: l00 hero movement step FUN_L00_00213880 in c\n\n* fix: l05 lift uses its own name for FUN_00213f38\n\n* overlay: rotation light update FUN_L00_0025f090 in c\n\n* overlay: l14 entity update FUN_L14_002b2600 in c\n\n* overlay: l15 mode slot cue FUN_L15_002edb20 in c\n\n* overlay: l14 group moby lookup by tag FUN_L14_002f12f0 in c\n\n* overlay: l04 mode slot cue FUN_L04_002e53a0 in c\n\n* overlay: l05 leap animation timing FUN_L05_00307570 in c\n\n* overlay: l13 lift update FUN_L13_002b39e0 in c\n\n* overlay: l02 shard debris update FUN_L02_002ebf20 in c\n\n* overlay: l03 rail path flyer FUN_L03_002d3918 in c\n\n* overlay: l05 path walker steer FUN_L05_00303b08 in c\n\n* overlay: l04 switch follower FUN_L04_002c6858 in c\n\n* overlay: l02 watcher npc update FUN_L02_002e1950 in c\n\n* overlay: hero speed clamp FUN_L00_00211be8 in c\n\n* overlay: l07 entity update twin FUN_L07_0030e720 in c\n\n* overlay: l04 path next FUN_L04_0029eb20 in c\n\n* overlay: l09 tumbling debris update FUN_L09_002ef430 in c\n\n* overlay: l04 vendor update FUN_L04_002e3078 in c\n\n* overlay: hero moby of interest check FUN_L01_00277fb8 in c\n\n* overlay: random delay timer update FUN_L14_002b2ed8 in c\n\n* overlay: camera user mode pick FUN_L01_00316030 in c\n\n* overlay: thrown moby landing prediction FUN_L00_002c8440 in c\n\n* overlay: lock-on target pick over the moby table FUN_L01_0030d308 in c\n\n* overlay: l06 listed-moby state check FUN_L06_002e9ea0 in c\n\nWalks the moby index list and returns 0 when a class-0x33B moby is outside states 0xFE/0xFD/0x10.\n\n* overlay: class-list moby lookup FUN_L05_00319598 in c\n\n* overlay: l09 shot update FUN_L09_00307d68 in c\n\n* overlay: l07 swooper update FUN_L07_003196e0 in c\n\n* overlay: l02 swivel turret update FUN_L02_002df3d8 in c\n\n* overlay: l06 hero-avoiding circler FUN_L06_002fbc88 in c\n\n* overlay: l07 breakable prop FUN_L07_00319f48 in c\n\n* overlay: l08 linked part chain update FUN_L08_002e2078 in c\n\n* overlay: grabbed moby state check FUN_L06_002ea5e0 in c\n\n* overlay: l09 heavy debris update FUN_L09_002ef9b0 in c\n\n* overlay: l12 troll damage and alert step FUN_L12_002e3528 in c\n\n* overlay: l04 collected riser FUN_L04_002e17d8 in c\n\n* overlay: l06 backdrop mesh quads FUN_L06_00300720 in c\n\n* overlay: l07 chaser path step FUN_L07_00313af0 in c\n\n* overlay: l04 type riser rise speed by moby class\n\n* overlay: l11 grabbed moby state check FUN_L11_00316160 in c\n\n* overlay: l18 launch idle group moby FUN_L18_002fc668 in c\n\n* overlay: l15 flocking step FUN_L15_002c52b8 in c\n\n* overlay: l11 three-part switch moby FUN_L11_002f2518 in c\n\n* overlay: l07 rope ray alias takes the scale before the target FUN_L00_00259888\n\n* overlay: l11 ship hud FUN_L11_00311d50 in c\n\n* overlay: l12 turret watcher update FUN_L12_002eb570 in c\n\n* overlay: l09 pebble spawner FUN_L09_002eaa50 in c\n\n* overlay: l12 watcher trigger state FUN_L12_003081b0 in c\n\n* overlay: l01 scrolling layer draw FUN_L01_002b96e0 in c\n\n* overlay: l06 hazard sparks FUN_L06_002f3d70 in c\n\n* overlay: l07 debris update FUN_L07_0030bbc8 in c\n\n* overlay: l06 beam quads FUN_L06_002ff680 in c\n\n* overlay: l12 watcher reads the watched moby state through the table bytes\n\n* overlay: l09 hovering voice moby update FUN_L09_002c5990 in c\n\n* overlay: l09 bubble update FUN_L09_0030b3b0 in c\n\n* overlay: l06 moby 1068 update FUN_L06_002fdbd0 in c\n\n* overlay: l11 count listed mobys in states 13 to 17 FUN_L11_00316090 in c\n\n* overlay: l12 lobbed projectile launch FUN_L12_00308708 in c\n\n* overlay: l08 water splash FUN_L08_002da0f0 in c\n\n* overlay: l07 segment-sphere nearest point FUN_L07_0029e6d8 in c\n\nClamps both sphere hits to the segment and keeps the closer one; p2 goes through one pointer so it stays in a single register.\n\n* overlay: l05 rising swing gate FUN_L05_00314eb0 in c\n\nFUN_L00_0025be00 returns a float; with that prototype the 0.0f target is materialised late as in retail.\n\n* overlay: l03 trooper hit knockback FUN_L03_002ca808 in c\n\nThe hit position is copied with a plain u128 move so the sq lands in the knockback call's delay slot.\n\n* overlay: ship ammo, health and edge flag read through hero fields in l11 and l17\n\n* overlay: l12 ogre damage and alert step FUN_L12_002e81e0 in c\n\n* overlay: l14 path distance follow FUN_L14_002ae7d8 in c\n\n* overlay: l15 spark toward target FUN_L15_0025e2c0 in c\n\n* overlay: l02 hud counter draw FUN_L02_0023cda8 in c\n\n* overlay: l07 bolt update FUN_L07_0030b6a8 in c\n\n* overlay: l03 spinner update FUN_L03_002d3e58 in c\n\n* overlay: l07 chaser speed ease FUN_L07_00313d30 in c\n\n* overlay: l07 spawned moby reset FUN_L07_0030af40 in c\n\n* overlay: l07 use shared names for vector and collision helpers in 00312948\n\n* overlay: l18 boss circles its arena node FUN_L18_002f6aa0 in c\n\n* overlay: l04 smoke puff trail FUN_L04_002c41e0 in c\n\nUses the interleaved FUN_L00_0026d000 prototype already used by puff_x/puff_y so the\nfloat args are set up in retail order.\n\n* overlay: l15 collision probe step-up FUN_L15_00247e90 in c\n\nDeclares FUN_L00_001f0d60 as (void *, float, int, void *), as shared 00257ef0 does,\nso a0 is set before f12 in retail order.\n\n* overlay: l10 type moby fields in 002ea1f0\n\n* overlay: l11 type moby fields in 0030e708\n\n* overlay: l12 type moby fields in 002ec720\n\n* overlay: l12 type moby fields in 0030b6c8\n\n* overlay: pick best target among class 0x359 mobys FUN_L06_002f34d8 in c\n\n* overlay: count frames the class 0xac moby stays outside the trigger zones FUN_L01_00302648 in c\n\n* overlay: reset camera from its preset table entry FUN_L05_003296e0 in c\n\n* overlay: l14 one-time unlock FUN_L14_00305408 in c\n\n* overlay: l13 fade in hold fade out FUN_L13_002e84d8 in c\n\n* overlay: l03 homing rocket update FUN_L03_002d43c8 in c\n\n* overlay: l04 lever door update FUN_L04_002c6bb8 in c\n\n* overlay: l05 hero orbit camera FUN_L05_003298d8 in c\n\n* overlay: removal helper takes struct moby in l10-l12 units\n\n* overlay: l10 type moby fields in 002df270\n\n* overlay: l11 type moby fields in 002cb668\n\n* overlay: l12 type moby fields in 003028c8\n\n* overlay: l08 target board build FUN_L08_002e1d70 in c\n\n* overlay: l08 hero lift update FUN_L08_002dbdb0 in c\n\n* overlay: l08 swinging gate update FUN_L08_002ea4c0 in c\n\n* overlay: shared message box and race results draw FUN_L00_002018c8 in c\n\n* decomp: message box and race results draw_dialog_text in c\n\n* overlay: l08 use shared names for water splash helpers in 002b8228\n\n* overlay: l07 name the rope vector and slot types in 00312948\n\n* overlay: l06 vendor voice line pick FUN_L06_00302400 in c\n\n* overlay: l12 type moby helpers as struct moby in 002bf140\n\n* overlay: l11 type moby helpers as struct moby in 0030c788\n\n* overlay: l11 type moby helpers as struct moby in 00315968\n\n* overlay: l10 type moby helpers as struct moby in 00295a38\n\n* overlay: l00 path point sampler FUN_L00_00262360 in c\n\n* overlay: mark moby killed and release its voice slot FUN_L15_002a35d8 in c\n\n* overlay: kill moby and clear its key table entry FUN_L00_002d5830 in c\n\n* overlay: type camera preset reset FUN_L05_003296e0 in c\n\n* overlay: l12 use moby fields in spawner FUN_L12_003076e0\n\n* overlay: l11 use hero moby fields in 00253a18\n\n* overlay: l12 use hero moby fields in 002461f0\n\n* overlay: shared cutscene frame update FUN_L00_00298f90 in c\n\nUses the unit's VendorCutscene/VendorMoby types (moved up), g_debug_menu and fade_level;\nD_0013C940's local struct gains the held/pressed pair retail reads as one doubleword.\n\n* overlay: l08 puff trail between two points FUN_L08_002da3f0 in c\n\n* overlay: music track request FUN_L01_0027a248 in c\n\n* overlay: l12 steer toward heading point FUN_L12_00271dd8 in c\n\n* overlay: shared pickup respawn update FUN_L01_00300220 in c\n\n* overlay: shared menu item label FUN_L00_0024a618 in c\n\n* overlay: l01 shrink and sink drifting moby FUN_L01_002e3208 in c\n\n* overlay: stream sector list entry FUN_L00_002451b8 in c\n\n* overlay: l08 gunship turret update FUN_L08_002e24e8 in c\n\n* decomp: give struct mobyclass its fields in moby.h\n\n* overlay: l11 and l12 read moby class fields through pclass\n\n* overlay: l09 path flyer step FUN_L09_0030a298 in c\n\n* overlay: l09 debris spawn FUN_L09_002ef868 in c\n\n* overlay: l05 read moby class fields through pclass\n\n* overlay: l07 read moby class fields through pclass\n\n* overlay: l08 read moby class fields through pclass\n\n* overlay: l13 read moby class fields through pclass\n\n* overlay: l14 read moby class fields through pclass\n\n* overlay: l16 read moby class fields through pclass\n\n* overlay: l17 read moby class fields through pclass\n\n* overlay: shared read moby class fields through pclass\n\n* overlay: rail lift update FUN_L03_002dccc0 in c\n\nRides the lift between the two rail path ends once the hero is in its trigger volume, offers the help prompt while it waits, and carries its collision record along.\n\n* overlay: take the size before the count in FUN_L00_0026bb70 and FUN_L00_0026bed0\n\nTheir other callers (002aa670.c, 002b96e0.c) already pass the float first, and FUN_L00_00273a68's argument setup only matches with this order. Still exact.\n\n* overlay: falling ember particle update FUN_L00_00273a68 in c\n\nDrifts under gravity until it hits its floor height, then bounces off in a smoke puff and on level 10 also spawns a glow and a spark.\n\n* overlay: read moby class fields through pclass in six more units\n\n* overlay: l14 path mover update FUN_L14_002aba80 in c\n\n* overlay: carrier moby grips, hands over and picks up its load FUN_L00_002c7a58 in c\n\n* overlay: moby hit box sweep FUN_L10_002c9958 in c\n\n* overlay: moby path point approach FUN_L14_002fdbb8 in c\n\n* overlay: path junction pairing FUN_L18_002d62e8 in c\n\n* overlay: l08 use struct moby fields instead of raw offsets\n\n* overlay: l09 use struct moby fields instead of raw offsets\n\n* overlay: l10 use struct moby fields instead of raw offsets\n\n* overlay: l11 use struct moby fields instead of raw offsets\n\n* overlay: l12 use struct moby fields instead of raw offsets\n\n* overlay: l13 use struct moby fields instead of raw offsets\n\n* overlay: l14 use struct moby fields instead of raw offsets\n\n* overlay: l15 use struct moby fields instead of raw offsets\n\n* overlay: l16 use struct moby fields instead of raw offsets\n\n* overlay: l17 use struct moby fields instead of raw offsets\n\n* overlay: l18 use struct moby fields instead of raw offsets\n\n* overlay: l14 match the path mover call to the typed FUN_L14_002ac2b8\n\n* overlay: flickering point light update FUN_L08_002f70a0 in c\n\nSeeds the flicker rings on spawn, fades the light out with camera distance, and creates or updates its point light while it is on screen.\n\n* overlay: l01 debris read moby fields in FUN_L01_002ffdc0 and FUN_L01_002ff860\n\n* overlay: l02 bots read moby fields through struct Moby in 002400c8\n\n* overlay: l02 read moby fields through struct Moby in 002e0dc0\n\n* overlay: l02 read moby fields through struct Moby in 002ebf20\n\n* overlay: l03 read moby fields through struct Moby in 002c9eb8\n\n* overlay: l04 read moby fields through struct Moby in 0029eb20\n\n* overlay: spray emitter particles and splashes FUN_L05_003150f0 in c\n\n* overlay: steer hovering moby toward goal and target FUN_L01_0030d880 in c\n\n* overlay: reset camera orbit and prepare preset paths FUN_L01_00314e98 in c\n\n* overlay: bounce debris and burst it into sparks FUN_L01_002f8718 in c\n\n* overlay: snap and pull the hero along grind rails FUN_L01_002f6328 in c\n\n* overlay: debug camera fly update FUN_L00_001f3aa0 in c\n\n* decomp: name moby group and save_id fields\n\n* overlay: swinging door update FUN_L15_002a3ba8 in c\n\n* decomp: use struct moby for the item preview mobys\n\n* overlay: l02 turn moby to its goal rotation FUN_L02_002df948 in c\n\n* overlay: l10 floor plate opens its door FUN_L10_002d92b8 in c\n\n* overlay: l06 burst particles up from a moby FUN_L06_002e9f30 in c\n\n* overlay: l06 animate four drifting strands FUN_L06_002f7000 in c\n\n* overlay: l06 throw spark bursts from a moby FUN_L06_002ea198 in c\n\n* overlay: vendor beam damage sweep FUN_L14_00302538 in c\n\nTraces the beam's two end lines against the level once, then sweeps four offset lines between them and damages whatever they cross, pushed away from the beam. Gives D_L14_001600EC its frame type.\n\n* overlay: hero slot-0 gadget button dispatch FUN_L02_0022ee00 in c\n\n* overlay: l03 read moby fields through struct Moby in 00292578\n\n* overlay: l03 read moby fields through struct Moby in 0029c8a8\n\n* overlay: l03 read moby fields through struct Moby in 002e2948\n\n* overlay: l04 read moby fields through struct Moby in 002c40d0\n\n* overlay: l03 use the moby group field in FUN_L03_002c6a20\n\n* overlay: l10 pass the position first to FUN_L00_001f2868\n\n* config: mark seven hand-written overlay functions as intentional asm\n\nThey hold raw .word instructions, hand-placed nops or a self-jumping poll\nloop, which no compiler output here produces.\n\n* overlay: l14 start a new unit at FUN_L14_002d6358\n\nFUN_L14_002d5f40 reads D_L14_0015F70C through $gp and FUN_L14_002d6358,\nright after it, through lui. One translation unit gives a global a single\ntreatment, so the original file ended between the two.\n\n* overlay: l14 racer waits for the race, rides its path and leaves FUN_L14_002d5f40 in c","measures":{"fuzzy_match_percent":68.1313,"total_code":3547652,"matched_code":2356188,"matched_code_percent":66.41542,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4242,"matched_functions":3488,"matched_functions_percent":82.225365,"complete_code":2356188,"complete_code_percent":66.41542,"complete_data":0,"complete_data_percent":0,"total_units":507,"complete_units":326}},{"timestamp":"2026-10-09T03:44:01Z","commit_sha":"246ecdf58e5a5a2a85fb6c30857f6770a8f41e46","commit_message":"decomp: promote four menu units (3500 B) (#128)","measures":{"fuzzy_match_percent":63.726646,"total_code":3547856,"matched_code":2190140,"matched_code_percent":61.731365,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4250,"matched_functions":3310,"matched_functions_percent":77.882355,"complete_code":2190140,"complete_code_percent":61.731365,"complete_data":0,"complete_data_percent":0,"total_units":510,"complete_units":304}},{"timestamp":"2026-10-08T21:38:31Z","commit_sha":"40cbd730e60035b0eb810c68fbf9201016c0fda3","commit_message":"decomp: replace local struct copies with shared include/ types (#127)","measures":{"fuzzy_match_percent":63.72437,"total_code":3547856,"matched_code":2186640,"matched_code_percent":61.632717,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4250,"matched_functions":3306,"matched_functions_percent":77.78824,"complete_code":2186640,"complete_code_percent":61.632717,"complete_data":0,"complete_data_percent":0,"total_units":510,"complete_units":302}},{"timestamp":"2026-10-08T20:16:44Z","commit_sha":"33b36ae9e4ede5b0ef97b214bf6c7fd466338dd5","commit_message":"decomp: decompilerizer batch 7 (#126)\n\n* decomp: improve FUN_0011b980\n\n* decomp: improve FillTransferWords\n\n* decomp: improve cmd_sem_init\n\n* decomp: improve _type2id\n\n* decomp: improve fast_add_rotations\n\n* decomp: improve LoadDefaultMpegQuantizerMatrix\n\n* decomp: improve sceDbcCreateSocket\n\n* decomp: improve select_world_object_resource_tables\n\n* decomp: improve FUN_00226b08\n\n* decomp: improve sound_options_menu\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve _sceFs_Rcv_Intr\n\n* decomp: improve _getRef0\n\n* decomp: recover read_mpeg streaming and callback contracts\n\n* decomp: improve render_vendor_capture_pass_sequence\n\n* decomp: improve update_view_context\n\n* decomp: improve draw_map_overlay\n\n* decomp: fix MPEG callback and timestamp contracts\n\n* decomp: improve fast_add_rotations\n\n* decomp: improve fast_add_rotations\n\n* decomp: improve music_transition\n\n* decomp: improve configure_graphics_projection\n\n* decomp: improve configure_graphics_projection\n\n* decomp: improve initialize_gameplay_sound_system\n\n* decomp: improve configure_graphics_projection\n\n* decomp: improve append_fullscreen_clear_strips\n\n* decomp: improve _doMC\n\n* decomp: improve sceCdRead\n\n* decomp: improve append_fullscreen_clear_strips\n\n* decomp: improve sceGsSetDefLoadImage\n\n* decomp: improve sceGsSetDefLoadImage\n\n* decomp: improve sceGsSetDefLoadImage\n\n* decomp: improve set_pal_mode\n\n* decomp: improve _getRef0\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve music_update\n\n* decomp: improve _getRef0\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve _getRef0\n\n* decomp: improve _getRef0\n\n* decomp: improve _getRef0\n\n* decomp: improve update_view_context\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve update_view_context\n\n* decomp: improve _getAllRefs\n\n* decomp: improve update_view_context\n\n* decomp: improve render_configured_text_label\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":63.72437,"total_code":3547856,"matched_code":2186640,"matched_code_percent":61.632717,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4250,"matched_functions":3306,"matched_functions_percent":77.78824,"complete_code":2186640,"complete_code_percent":61.632717,"complete_data":0,"complete_data_percent":0,"total_units":510,"complete_units":302}},{"timestamp":"2026-10-08T16:52:54Z","commit_sha":"48c75b5d4b21085678430097616024e68fd8bc70","commit_message":"overlay: use struct Hero instead of local hero struct copies (#125)\n\n* overlay: use struct Hero instead of the local GameState copy in five hero units (l15, l18, l17, l06, shared)\n\nField accesses were rewritten by offset (scratch script). hero.h gains neutral unk fields in padding at 0x130, 0x510-0x530, 0x580, 0x5D0, 0x5D4, 0x5DC, 0x610, 0x614 and 0x2218; unk5AC and unk618 become f32/s32 unions because these units use them as floats while other units zero them as ints. l18, l17, l06 and shared keep a hero_b alias for the second name of D_0013F350, which gcc reloads through.\n\n* overlay: use struct Hero instead of local hero copies in 002377b8, 0021b698, 002097a0 and 00226f10\n\n* overlay: use struct Hero instead of the local GameState copy in five hero units (l03, l11, l12, l14, l08)\n\n* overlay: use struct Hero in the l05 and l16 hero units and cast hero moby pointers to MobyView explicitly\n\nhero.h splits unk6C0 into Vec4 unk6C0 / f32 unk6D0 / unk6D4 (FillTransferWords callers pass &hero.unk6C0), adds neutral fields at 0x720-0x790, 0x854-0x88F, 0x8A4, 0x8CC, 0x8D0, 0x2230 and 0x2234, and makes unk8B8 an f32/s32 union (zeroed as an int elsewhere). The seven converted hero units now compile without pointer-type warnings.\n\n* overlay: use struct Hero instead of seven local hero views in shared/ui/help/0020c758.c\n\n* overlay: replace the GS GG hero copies with struct Hero and make hero 0x2D8/0x2E0/0x30C/0x30E unions\n\n* overlay: use the hero 0x2D8/0x2E0/0x30C/0x30E union members in the l05 and l16 hero units\n\n* overlay: use struct Hero instead of the local hero copies in l05/00239fc0 and shared/gameplay/entities/002b2100\n\n* overlay: use struct Hero for the GS, 002121c0 and four raw byte hero views in shared/ui/help/0020c758.c\n\n* overlay: type hero 0xD08 as two slot pointers and drop the last local hero views in shared/ui/help/0020c758.c","measures":{"fuzzy_match_percent":63.724304,"total_code":3547856,"matched_code":2185532,"matched_code_percent":61.601486,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4250,"matched_functions":3305,"matched_functions_percent":77.76471,"complete_code":2185532,"complete_code_percent":61.601486,"complete_data":0,"complete_data_percent":0,"total_units":510,"complete_units":302}},{"timestamp":"2026-10-08T15:59:52Z","commit_sha":"fabff0c3496e1759bc6beee51bc0383f0bc61c4a","commit_message":"decomp: audit struct field names and keep single-use layouts in their .c file (#124)\n\n* decomp: audit MenuScreen and MenuSystem field names\n\n* overlay: share OvlQuad instead of local signed TImode quad typedefs\n\n* chore: audit pad, disc table and trail field names\n\n* chore: keep single-use layouts in their .c file\n\n* overlay: use struct Hero instead of the local GS copy in shared/ui/help/001fe778.c","measures":{"fuzzy_match_percent":63.724304,"total_code":3547856,"matched_code":2185532,"matched_code_percent":61.601486,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4250,"matched_functions":3305,"matched_functions_percent":77.76471,"complete_code":2185532,"complete_code_percent":61.601486,"complete_data":0,"complete_data_percent":0,"total_units":510,"complete_units":302}},{"timestamp":"2026-10-08T15:33:46Z","commit_sha":"6075d36a3024ef8c66187bd3776d42e53c068f3b","commit_message":"decomp: overlay wave and readable shared structs (#123)\n\n* overlay: plain externs for small globals, fun_l00_002591d0 exact in c\n\nA plain extern of a small global is one macro load: the assembler keeps it absolute outside a delay slot and makes it $gp-relative inside one, which is the retail mix. The section(\".sdata\") aliases for scalars are gone; only two over-8-byte types keep it.\n\n* overlay: fun_l10_002befe8 exact in c\n\n* overlay: four more level 00-09 functions exact in c\n\n* overlay: fun_l06_00300c60 exact in c, l00 0024e010 is a copy of fun_0020bd58\n\n* overlay: twenty more level 10-18 functions exact in c, plain externs where retail uses lui\n\n* overlay: two more level 00-09 functions exact in c, plain externs where retail uses lui\n\n* overlay: fun_l07_0030ed30 and fun_l07_0030f308 exact in c\n\n* overlay: fun_l07_00317cb0 and fun_l00_002b9310 exact in c\n\n* overlay: thirteen more level 10-18 functions exact in c\n\n* overlay: five more level 00-09 functions exact in c\n\n* overlay: four more level 10-18 functions exact in c, ps2eeas label before align kept on the nop\n\n* chore: overlay copies use the shared qcopy and qzero, no inline .extern\n\n* chore: flat overlay files move into group directories, shared qcopy_nc\n\n* chore: named globals in headers, one menu system struct, recovered call-site names\n\n* chore: stub-only and classified overlay files move into group directories\n\n* chore: overlay call sites use recovered names and the shared globals\n\n* chore: one DEG_TO_RAD for overlay angle math, more function comments\n\n* chore: shared hero struct, dedupe library structs, name disc table and draw config, refresh catalog\n\n* chore: shared overlay types in headers, path hop out-params named, overlay call sites follow catalog names\n\n* chore: name overlay path functions, classify six overlay files\n\n* chore: one disc table and music stream state, named stream read fields\n\n* chore: hero fields read by overlays, shared mode freeze and packet cursor names\n\n* chore: classify 19 overlay files, one-line comments on shared overlay functions\n\n* chore: one memory card state struct, menu system views merged, disc table movie pairs\n\n* chore: small overlay hero views use the shared hero struct\n\n* chore: hud state struct, full hero layout, named menu and pad fields, classify remaining overlay files\n\n* chore: shared sceMpeg and libmpeg decoder structs, shared pad state, named mpeg fields\n\n* chore: overlay hero state machines use the shared hero struct, named hero state fields\n\n* chore: shared menu screen and menu page structs, sdk sif client data, named menu fields\n\n* chore: menu screen per-screen layouts, sdk sema param, screen struct, named menu fields\n\n* chore: hero_set_state named in every level, raw hero offsets become fields, moby trail struct\n\n* chore: full menu system struct, map state views merged, vi buffer struct, named fields\n\n* chore: more overlay hero views on the shared struct, health and collision hit named\n\n* chore: menu page views on shared menu structs, text list and stream screen layouts\n\n* chore: usage stats struct, per-level hero animation tables named\n\n* chore: hero sub-structs, readable menu, map, music and memory card headers, layout checks\n\n* chore: item slot code in help overlays uses hero item fields\n\n* chore: overlay pad merged into pad state with named fields, overlay types split into headers\n\n* chore: one packet cursor union, merged mpeg decoder and audio decoder structs, music views in overlays\n\n* chore: weakly supported names back to placeholders, keep rac1-decomp notice\n\n* fix: progress counts overlay functions defined under a C name bound to their label","measures":{"fuzzy_match_percent":63.724304,"total_code":3547856,"matched_code":2185532,"matched_code_percent":61.601486,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4250,"matched_functions":3305,"matched_functions_percent":77.76471,"complete_code":2185532,"complete_code_percent":61.601486,"complete_data":0,"complete_data_percent":0,"total_units":510,"complete_units":302}},{"timestamp":"2026-10-08T08:40:47Z","commit_sha":"5e5818adb67a6384c9c2673313b80190d048b51f","commit_message":"decomp: promote vfprintf_r (5400 B) (#122)\n\nThe C body already matched. Retail keeps all of the unit's read-only data in\none block at 0x1524E0, in source order: blanks, zeroes, \"Inf\", \"NaN\", the\nlower-case digits, \"(null)\", the upper-case digits, the \"bad base\" message,\n\"0\", \".\" and the switch table. The compiler put the five short literals in\n.sdata, so they become block-scope statics in .rodata, and a\nRODATA_OVERLAYS entry places the block (file offset 0x53460). The function\nis defined under its retail name _vfprintf_r; the FUN_00116e20 alias had no\ncounterpart in the expected object and broke the objdiff report.\n\nmake elf: PASS, make check: OK, make overlays: PASS.","measures":{"fuzzy_match_percent":63.010723,"total_code":3547908,"matched_code":2160248,"matched_code_percent":60.887936,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4252,"matched_functions":3249,"matched_functions_percent":76.4111,"complete_code":2160248,"complete_code_percent":60.887936,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":299}},{"timestamp":"2026-10-08T07:10:08Z","commit_sha":"f0491636b5bef551a81bd412752d2d57795a0513","commit_message":"decomp: promote printfloat (360 B) (#121)\n\nThe C body already matched (check-unit: Object matches). Promotion needed\nits three f64 literals placed at their retail address, so printfloat gets a\nRODATA_OVERLAYS entry (0x152798, file offset 0x53718) like _getpic.\nmake elf: PASS, make check: OK.","measures":{"fuzzy_match_percent":62.85852,"total_code":3547908,"matched_code":2154848,"matched_code_percent":60.735737,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4252,"matched_functions":3248,"matched_functions_percent":76.38758,"complete_code":2154848,"complete_code_percent":60.735737,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":298}},{"timestamp":"2026-10-08T03:20:25Z","commit_sha":"30e13510b5fc1a80fe9a8ca60030cffea2fcb1a5","commit_message":"decomp: overlay wave (67 functions exact) and no per-unit compiler options (#120)\n\n* config: drop per-unit flags from 5 game units\n\nfun_00221968, calculate_voice_volume, vu1_add_g_sregister, reset_graphics\nand create_menu_preview_moby are exact with the default game-compiler\nflags. fun_0021b6d8 and fun_002075e8 keep theirs, with the blocker noted.\n\n* config: drop -mastra-* unit options and the at-store policy\n\nThe 9 extern-buffer units use sda externs instead of the option, and\npatch 0034 is retired. The patched EE-GCC keeps sd-saves and\nvolatile-delay always on, and its volatile-store split writes the noat\nbracket itself, so picturecodingextension needs no asm policy.\ncalculate_voice_distance_volume moves to the game compiler and\n_lastFrame becomes C.\n\n* config: no per-unit flags or opt-in compiler options left\n\nfun_0021b6d8 writes its defaults back into the parameters and needs no\nfixed registers. fun_002075e8 was the tail of fun_00207580, now one C\nunit. fun_00226848 is exact in C. The patched EE-GCC drops its unused\nopt-in options, and the game compiler is rebuilt without patch 0034.\n\n* overlay: fun_l01_002ef478 exact in c\n\n* overlay: 10 more level functions exact in c, fix the l09 catalogue boundary\n\n* overlay: fun_l11_002d0710 exact in c\n\n* overlay: fun_l10_002cc2e8 exact in c\n\n* overlay: 5 more level functions exact in c\n\n* overlay: fun_l13_003058a8 exact in c\n\n* config: fun_l00_002503c0 is intentional vu0 asm\n\n* overlay: fun_l13_00309e88 exact in c\n\n* overlay: fun_l01_0026e008 and fun_l05_002899f8 exact in c\n\n* overlay: 3 more level functions exact in c\n\n* overlay: fun_l04_0024c4f0 exact in c\n\n* overlay: 4 more level functions exact in c\n\n* overlay: fun_l15_002f78e0 and fun_l14_002b39a0 exact in c\n\n* overlay: fun_l14_002ef5a8 and fun_l14_00316748 exact in c\n\n* overlay: fun_l00_002779c8 and fun_l02_002dae88 exact in c, fix two catalogue starts\n\n* overlay: fun_l14_002b5d18 exact in c\n\n* config: mark three hand-written overlay stubs as intentional asm\n\n* overlay: fun_l11_00311c80 and fun_l15_00299ff8 exact in c\n\n* overlay: fun_l05_0023b378 and fun_l00_0027f448 exact in c\n\n* overlay: fun_l14_002ac2b8 exact in c, true prototype for fun_l11_00311948\n\n* overlay: six more level 00-09 functions exact in c\n\n* overlay: five more level 10-18 functions exact in c\n\n* overlay: five more level 10-18 functions exact in c\n\n* overlay: five more level 00-09 functions exact in c\n\n* overlay: fun_l18_002f06c0 exact in c\n\n* overlay: split shared vendor 002e5e38 into its own unit, fun_l00_002e6bf8 and fun_l06_00300278 exact","measures":{"fuzzy_match_percent":62.85802,"total_code":3547908,"matched_code":2154488,"matched_code_percent":60.72559,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4252,"matched_functions":3247,"matched_functions_percent":76.36407,"complete_code":2154488,"complete_code_percent":60.72559,"complete_data":0,"complete_data_percent":0,"total_units":513,"complete_units":298}},{"timestamp":"2026-10-08T02:50:25Z","commit_sha":"379e3cabad5e8e27e2e48ec3ed0868f957af3990","commit_message":"decomp: decompilerizer batch 6 (#119)\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve FillTransferWords\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve sceGsSetDefLoadImage\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve sceGsSetDefLoadImage\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve select_world_object_resource_tables\n\n* decomp: improve _csc_storeRefImage\n\n* decomp: improve set_pal_mode\n\n* decomp: improve sound_options_menu\n\n* decomp: improve draw_sound_menu\n\n* decomp: improve LoadDefaultMpegQuantizerMatrix\n\n* decomp: recover provisional graphics synchronization C\n\n* decomp: improve initialize_gameplay_sound_system\n\n* decomp: improve get_frame_texture\n\n* decomp: improve _vfprintf_r\n\n* decomp: improve printfloat\n\n* decomp: improve WriteDmaChannel\n\n* decomp: improve _type2id\n\n* decomp: improve wait_for_graphics_pipeline_idle\n\n* decomp: improve wait_for_graphics_pipeline_idle\n\n* decomp: improve render_vendor_buy_label_pass\n\n* decomp: improve get_frame_texture\n\n* decomp: improve snd_start_sound_system\n\n* decomp: improve sceCdInit\n\n* decomp: improve set_pal_mode\n\n* decomp: improve draw_sound_menu\n\n* decomp: improve register_object_render_class\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve sceGsSetDefDispEnv\n\n* decomp: improve register_object_render_class\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve sound_update\n\n* decomp: improve _vfprintf_r\n\n* decomp: improve _vfprintf_r\n\n* docs: remove graphics synchronization recovery notes\n\n* decomp: recover PIF upload layouts and register contract\n\n* decomp: repair read_mpeg C and recover streaming contracts\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":62.06185,"total_code":3548300,"matched_code":2126484,"matched_code_percent":59.929657,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4258,"matched_functions":3179,"matched_functions_percent":74.65946,"complete_code":2126484,"complete_code_percent":59.929657,"complete_data":0,"complete_data_percent":0,"total_units":518,"complete_units":288}},{"timestamp":"2026-10-07T19:20:33Z","commit_sha":"5ccfa1fb314e9cb43f6ff9a43249523e1c4a5310","commit_message":"decomp: transition_load_wad and service_level_archive_load exact (#118)\n\n* decomp: transition_load_wad exact in C\n\n* decomp: service_level_archive_load exact in C\n\n* docs: rac1-decomp code is MIT (ported before 8753a55)","measures":{"fuzzy_match_percent":62.08525,"total_code":3546752,"matched_code":2124468,"matched_code_percent":59.89897,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4254,"matched_functions":3176,"matched_functions_percent":74.65914,"complete_code":2124468,"complete_code_percent":59.89897,"complete_data":0,"complete_data_percent":0,"total_units":518,"complete_units":286}},{"timestamp":"2026-10-07T18:29:56Z","commit_sha":"5157fcd0233c3f079898cf51df206378eb6b5a51","commit_message":"docs: class tables and instance colours at the level loaders (#117)","measures":{"fuzzy_match_percent":62.078312,"total_code":3546752,"matched_code":2121784,"matched_code_percent":59.823296,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4254,"matched_functions":3174,"matched_functions_percent":74.61213,"complete_code":2121784,"complete_code_percent":59.823296,"complete_data":0,"complete_data_percent":0,"total_units":518,"complete_units":285}},{"timestamp":"2026-10-07T17:13:01Z","commit_sha":"d53520a7c3fe1013e9007b2ca0b71866f981cf14","commit_message":"docs: sky, tfrag and gameplay file layouts at their functions (#116)\n\n* docs: sky, tfrag and gameplay file layouts at their functions\n\n* docs: plain English for the layout comments","measures":{"fuzzy_match_percent":62.078312,"total_code":3546752,"matched_code":2121784,"matched_code_percent":59.823296,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4254,"matched_functions":3174,"matched_functions_percent":74.61213,"complete_code":2121784,"complete_code_percent":59.823296,"complete_data":0,"complete_data_percent":0,"total_units":518,"complete_units":285}},{"timestamp":"2026-10-07T17:08:07Z","commit_sha":"5281ce30378a6399fd0106fbdfd3a36f27595595","commit_message":"decomp: 106 overlay functions from their exact twins (#115)\n\n* decomp: 82 overlay functions from their exact twins\n\n* decomp: one more overlay function from its twin\n\n* decomp: 16 more overlay twins, constants and blocks re-paired\n\n* decomp: 5 overlay twins with float constants and shifted fields\n\n* decomp: 2 overlay functions migrated\n\n* overlay: drop provenance comments copied into twin ports, duplicate prototypes","measures":{"fuzzy_match_percent":62.078312,"total_code":3546752,"matched_code":2121784,"matched_code_percent":59.823296,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4254,"matched_functions":3174,"matched_functions_percent":74.61213,"complete_code":2121784,"complete_code_percent":59.823296,"complete_data":0,"complete_data_percent":0,"total_units":518,"complete_units":285}},{"timestamp":"2026-10-07T14:51:06Z","commit_sha":"d1af2e38c7c52af84dcc74de594a3a8671edff9e","commit_message":"fix: overlay catalogue tells field-offset twins apart, not-copies.txt removed (#114)\n\n* overlay: catalogue without not-copies.txt\n\n* overlay: catalogue keeps field offsets off a complete address, not-copies.txt gone\n\n* decomp: 6 overlay functions the catalogue used to merge into their twins","measures":{"fuzzy_match_percent":61.394756,"total_code":3546752,"matched_code":2097540,"matched_code_percent":59.139744,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4254,"matched_functions":3072,"matched_functions_percent":72.214386,"complete_code":2097540,"complete_code_percent":59.139744,"complete_data":0,"complete_data_percent":0,"total_units":518,"complete_units":230}},{"timestamp":"2026-10-07T13:53:44Z","commit_sha":"73e5f5ebcd69dc834279776166d7dfb8cc40c6c4","commit_message":"decomp: 8 overlay functions, 3 exe units, every overlay copy proven (#113)\n\n* decomp: set_moby_animation migrated, split fun_0022e1b0 out of a text gap\n\n* overlay: migrate the l16 transport update, build its unit with sn\n\n* overlay: migrate the l16 movement limiter, build its unit with sn\n\n* overlay: migrate an l00 vendor slot release\n\n* overlay: migrate the l00 vendor pane animation\n\n* overlay: migrate the l02 sentry update\n\n* overlay: migrate the l12 challenge tracker\n\n* overlay: migrate the l16 pursuer hit reaction\n\n* overlay: migrate the l16 walker path step\n\n* overlay: prove every copy of a function, strict catalogue fingerprint\n\nCopies in other places are placed and compared too; callers of split\nrows resolve to the right twin; 30 functions that called or pointed at\na look-alike twin now name the retail callee. Promoted fun_00213928,\nfun_001e8d08 and fun_0022e1b0 into src/gameplay. The proof caches\nparsed objects and relocations, so make overlays runs in about a minute.\n\n* config: rodata overlays for promoted fun_001e8d08 and fun_00213928\n\n* overlay: split look-alike places the copy proof rejects into their own rows\n\nThe per-copy proof lists places an exact function's C cannot build (a\nword it does not relocate differs) in config/overlays/us/not-copies.txt;\nthe catalogue gives each its own row. Callers that named the merged row\nnow call the twin retail calls.\n\n* overlay: keep stub files in their subsystem folders","measures":{"fuzzy_match_percent":61.58143,"total_code":3535572,"matched_code":2097276,"matched_code_percent":59.319283,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4331,"matched_functions":3066,"matched_functions_percent":70.79196,"complete_code":2097276,"complete_code_percent":59.319283,"complete_data":0,"complete_data_percent":0,"total_units":524,"complete_units":229}},{"timestamp":"2026-10-07T09:56:14Z","commit_sha":"d4e06fc87765c27abc7f299c755bf10a20fefc8c","commit_message":"fix: level header 0x10/0x18 are the gameplay archives, not sound (#112)","measures":{"fuzzy_match_percent":61.845406,"total_code":3503736,"matched_code":2086736,"matched_code_percent":59.557453,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4130,"matched_functions":3057,"matched_functions_percent":74.01937,"complete_code":2086736,"complete_code_percent":59.557453,"complete_data":0,"complete_data_percent":0,"total_units":434,"complete_units":218}},{"timestamp":"2026-10-07T06:53:11Z","commit_sha":"dda313abd15acba9309c8b9ddfe79d2321ad4625","commit_message":"overlay: 25 migrated overlay functions + 41 new matches (#111)\n\n* overlay: 25 migrated overlay functions\n\n* overlay: FUN_L00_002ac910 on SN\n\n* overlay: FUN_L00_00269b70 on SN\n\n* overlay: FUN_L03_00292578 on SN\n\n* overlay: FUN_L13_002f8a78 on SN\n\n* overlay: FUN_L13_00316f48\n\n* overlay: FUN_L14_002ed280\n\n* overlay: FUN_L01_002e0bd8\n\n* overlay: FUN_L04_002cdda0\n\n* overlay: FUN_L14_002b2f60\n\n* overlay: FUN_L05_0030e1f8\n\n* overlay: FUN_L18_002efb88\n\n* overlay: FUN_L08_002dc180\n\n* overlay: FUN_L16_002e7ba0\n\n* overlay: FUN_L00_002c3888\n\n* overlay: FUN_L01_002f4428\n\n* overlay: FUN_L16_002e7f80\n\n* overlay: FUN_L10_00295c20\n\n* overlay: FUN_L08_002e4e90\n\n* overlay: FUN_L00_002c3888 use correct callee names\n\n* overlay: FUN_L00_0025f3e8\n\n* overlay: FUN_L16_002e37a0\n\n* overlay: FUN_L01_002ffdc0\n\n* overlay: FUN_L11_00309098\n\n* overlay: FUN_L16_002cf850\n\n* overlay: FUN_L10_002eaa08\n\n* overlay: FUN_L02_002da3d8\n\n* overlay: FUN_L16_002cf9f8\n\n* overlay: FUN_L06_002f7628\n\n* overlay: FUN_L13_002e1348\n\n* overlay: FUN_L02_002ec228\n\n* overlays: match FUN_L06_002f32f0\n\n* overlay: FUN_L02_002dd2a8\n\n* overlay: FUN_L14_00305680\n\n* overlays: match FUN_L05_0030bf98\n\n* overlay: FUN_L02_0020bc88 (SN unit)\n\n* overlay: FUN_L08_002f1378\n\n* overlays: match FUN_L05_00303e50\n\n* overlay: FUN_L03_0024fba8\n\n* overlays: match FUN_L11_00315f58\n\n* overlay: FUN_L02_002e1fb8\n\n* overlay: FUN_L06_002f3640\n\n* overlays: match FUN_L08_002ea398\n\n* cleanup: name locals and describe functions in l01-l03 overlay ports\n\n* cleanup: name moby/data locals in l02-l08 overlay functions\n\n* cleanup: name moby params and comment overlay functions in l10-l16\n\n* cleanup: use Moby fields for state and position in l11, l14, l18 overlay functions\n\n* cleanup: name locals and describe functions in shared entity, camera and effect code\n\n* cleanup: move l01-l04 overlay units into gameplay and math directories\n\n* cleanup: move l05-l12 overlay units into gameplay directories\n\n* cleanup: move l13-l18 overlay units into gameplay directories\n\n* cleanup: move flat shared overlay units into rendering and gameplay directories","measures":{"fuzzy_match_percent":61.845406,"total_code":3503736,"matched_code":2086736,"matched_code_percent":59.557453,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4130,"matched_functions":3057,"matched_functions_percent":74.01937,"complete_code":2086736,"complete_code_percent":59.557453,"complete_data":0,"complete_data_percent":0,"total_units":434,"complete_units":218}},{"timestamp":"2026-10-07T02:44:36Z","commit_sha":"d6ad249f7c177edbcb67b33123306f4c98e985c0","commit_message":"decomp: decompilerizer batch 5 (#109)\n\n* decomp: improve fast_decompress\n\n* decomp: improve init_dma\n\n* decomp: promote startlevel and improve level archive loading\n\n* decomp: improve SignExtendPackedValue\n\n* decomp: improve copy_matrix3x4\n\n* decomp: improve set_moby_animation\n\n* decomp: improve _type2id\n\n* decomp: improve LoadDefaultMpegQuantizerMatrix\n\n* decomp: improve sceDbcCreateSocket\n\n* decomp: improve mode_freeze_init\n\n* decomp: improve initialize_gameplay_sound_system\n\n* decomp: improve FUN_00121190\n\n* decomp: improve printfloat\n\n* decomp: improve service_level_archive_load\n\n* decomp: improve sound_options_menu\n\n* decomp: improve music_update\n\n* decomp: improve font_print_window\n\n* decomp: improve update_menu_entry_actions\n\n* decomp: improve transition_load_wad\n\n* decomp: improve render_level_effects_and_screen_sprites\n\n* decomp: clarify fast_decompress validation limits\n\n* decomp: clarify init_dma validation limits\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":60.78836,"total_code":3503736,"matched_code":2049700,"matched_code_percent":58.500412,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4130,"matched_functions":2991,"matched_functions_percent":72.42131,"complete_code":2049700,"complete_code_percent":58.500412,"complete_data":0,"complete_data_percent":0,"total_units":434,"complete_units":215}},{"timestamp":"2026-10-07T02:41:36Z","commit_sha":"1f872bdb26e51ea08cab89140a12b7b0863cbe0c","commit_message":"overlay: match four functions (376 bytes) (#110)","measures":{"fuzzy_match_percent":60.80501,"total_code":3502776,"matched_code":2048584,"matched_code_percent":58.484585,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4128,"matched_functions":2990,"matched_functions_percent":72.432175,"complete_code":2048584,"complete_code_percent":58.484585,"complete_data":0,"complete_data_percent":0,"total_units":434,"complete_units":215}},{"timestamp":"2026-10-06T19:25:14Z","commit_sha":"80789c2ff1b1de1990510e8bc3c9cd25a4ee6133","commit_message":"refactor: recover type, variable and function names (#108)\n\n* refactor: name include guards LOMBYTE_<path>_H\n\nReplaces the inherited RNCDECOMP_ and RNC_ guard prefixes with one rule:\nLOMBYTE_ plus the header path from include/ or src/.\n\n* refactor: share the UpdateCam camera record type\n\nThe camera record had five local layouts (Camera, CameraRecord, Moby,\nM2c_D_001870C0). One struct UpdateCam, named after the recovered\nCamera_*__FP9UpdateCam symbols, now lives in\ninclude/rnc/gameplay/camera/update_cam.h with the camera type table.\nupdate_moby and draw_moby were camera dispatchers through that table;\nthey take their recovered names camera_run_setup_to_new_cam and\ncamera_exit and move to gameplay/camera.\n\n* refactor: name locals and parameters by use (187 files)\n\nReplaces m2c names (arg0, temp_*, var_*) with names taken from how the\nvalue is used, the callee, or the Sony SDK prototype. Values whose\nmeaning is not clear keep their old names.\n\n* refactor: name locals in level overlays by use\n\nrecord_index for the help record slot, prototype parameters matching\nthe ELF definitions, and a few obvious parameters.\n\n* refactor: share struct DmaTag and TagPtr\n\n30 files carried their own copy of the DMA tag quadword under four\nspellings (w0/w2/w3, dma_control/address, GraphicsDmaTag,\nRenderPacketCursor). They now include rnc/rendering/dma_tag.h with\nfields tag, addr, vif0, vif1.\n\n* refactor: share the Vec4 quadword vector union\n\n29 files defined the same u128/f32[4] union as Vec or Vec4. It now\nlives in rnc/math/vector.h as Vec4.\n\n* refactor: share struct Moby across matched units\n\nSix units carried partial Moby layouts. They now include\nrnc/gameplay/entities/moby.h (0x100 bytes, fields named only where a\nmatched function uses them). The animation fields at 0x50-0x6C are\nnamed from update_moby_animation_state: frame/seq for the current\nsequence, prev_frame/prev_seq for the blend source.\n\n* refactor: replace m2c placeholder struct tags with names from use\n\nFile-local struct M2c_arg0 / M2c_D_<addr> / M2c_temp_* tags become\nnames such as MpegDecoder, MenuScreen, GameState, AudioDecoder.\nPartial views of a global whose role is unclear are named\nGlobals_<addr> consistently across files.\n\n* docs: trim the PR template to Before, After and Verification\n\n* refactor: recovered ezmpeg names and original type names\n\nNine video/display units carried generic names (get_state_table_word,\nset_state_field, ...) although the recovered symbols at their\naddresses are Sony ezmpeg functions with matching bodies:\nreadBufEndGet, scTag2, videoDecAbort, videoDecSetState, voBufIsFull,\nvoBufIsEmpty, voBufDecCount, startDisplay, endDisplay. They take those\nnames and move to video/.\n\nStruct tags follow the mangled parameter types where known (ReadBuf,\nViBuf, VideoDec, AudioDec, PAD), and the remaining M2c_* tags in the\nper-unit headers get names from use; partial views of a global whose\nrole is unclear are Globals_<addr> everywhere.\n\n* refactor: Sony SDK type names and player-update struct names\n\nSDK structs whose layout matches the Sony headers take their names:\nSemaParam, ThreadParam, sceSifClientData, sceSifServeData,\nsceSifDmaData, sceCdRMode, sceDmaChan, sceGsDrawEnv1, sceGsDispEnv.\n\nThe 12 per-level copies of the player update code name their structs\nfrom use: GameState, PadState, VoiceSlot (D_0013E550 entries),\nPlayerSpeedTuning, PlayerJointTable; unclear level tables are\nLevelTable_<old>.\n\n* refactor: move hero overlay code out of ui/help\n\nThe level files named ui_help_<addr> (and three shared ui/help units)\nhold the hero state machine, movement and animation code that sits\nafter ui/help in memory, not help prompts. They move to\n<level>/gameplay/hero/<addr>.c and shared/gameplay/hero/.\n\n* refactor: take recovered symbol names where the code confirms them\n\n25 functions whose recovered symbol was ignored now use it, after\nchecking the body against the name:\n- movie player (Sony ezmpeg): init_all, term_all, err_message,\n  proceed_audio, set_image_tag, handler_end_image, cpy2area,\n  set_d3_chcr, set_d4_chcr, video_dec_main, dec_bs0, mpeg_error,\n  mpeg_nodata (were named as audio-system or generic helpers);\n- music_pause / music_unpause (were \"render state\" functions; they\n  write the music stream commands, so D_001516D0 is MusicStreamState);\n- memcard_restore_game, snd_get_doppler_pitch_mod, reset_draw_globals,\n  font_set_window, put_draw_buffer_large/small, aa_blur_pass,\n  hud_get_icon_index, get_icon_frame, vu0_load_micro_program (VIF0, not\n  VIF1).\nUnits move to the directory of their subsystem.\n\n* refactor: sync catalog source_path with moved units\n\n* refactor: audit fixes before review\n\nRestore sce_sif_init_cmd.c to its main version (the merge had left the\nNON_MATCHING body half renamed and uncompilable), and point two\ncomments at the renamed units.\n\n* docs: reword the AI note in the README\n\n* docs: verification checklist in PR template","measures":{"fuzzy_match_percent":60.794277,"total_code":3502776,"matched_code":2048208,"matched_code_percent":58.47385,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4128,"matched_functions":2986,"matched_functions_percent":72.33527,"complete_code":2048208,"complete_code_percent":58.47385,"complete_data":0,"complete_data_percent":0,"total_units":434,"complete_units":215}},{"timestamp":"2026-10-06T18:11:36Z","commit_sha":"cdcbd31125e948a2f393bf2d70807b9ab36024ed","commit_message":"decomp: Compilierizer batch 4 (#107)\n\n* decomp: improve sceSifCallRpc\n\n* decomp: improve _doMC\n\n* decomp: improve kputchar\n\n* decomp: improve SignExtendPackedValue\n\n* decomp: improve FUN_0011b980\n\n* decomp: improve ftoi\n\n* decomp: improve signal_native_cd_delay_alarm\n\n* decomp: improve cmd_sem_init\n\n* decomp: improve _type2id\n\n* decomp: improve LoadDefaultMpegQuantizerMatrix\n\n* decomp: improve printfloat\n\n* decomp: improve sceDbcCreateSocket\n\n* decomp: improve sceCdRead\n\n* decomp: improve draw_sound_menu\n\n* decomp: improve FUN_00121190\n\n* decomp: improve _csc_storeRefImage\n\n* decomp: improve sceFsInit\n\n* decomp: improve UpdateMpegReferenceImages\n\n* decomp: improve sceCdInit\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve set_pal_mode\n\n* decomp: improve draw_localized_three_option_menu\n\n* decomp: improve sample_surface_height_map\n\n* decomp: improve FUN_00226b08\n\n* decomp: improve draw_checking_memory_card_data_menu\n\n* decomp: improve scale_game_frames\n\n* decomp: improve fast_add_rotations\n\n* decomp: improve fast_difference_between_rotations\n\n* decomp: improve update_visible_resident_objects\n\n* decomp: improve fast_normalize_angle\n\n* decomp: improve read_mpeg\n\n* decomp: improve vi_buf_restart_dma\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve configure_graphics_projection\n\n* decomp: improve initialize_graphics_buffer_descriptors\n\n* decomp: improve service_level_archive_load\n\n* decomp: improve advance_accelerated_scalar\n\n* decomp: improve update_gameplay_frame\n\n* decomp: improve append_rotated_sprite_quad\n\n* decomp: improve _getRef0\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve upload_mip_texture\n\n* decomp: improve music_update\n\n* decomp: improve _sceFs_Rcv_Intr\n\n* decomp: improve register_object_render_class\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve update_item_preview_binding\n\n* decomp: improve draw_level_selection_map\n\n* decomp: improve draw_items_menu\n\n* decomp: improve update_streamed_moby_animation\n\n* decomp: improve startlevel\n\n* decomp: improve update_menu_grid_selection\n\n* decomp: improve transition_do_transition\n\n* decomp: improve render_environment_mapped_object\n\n* decomp: improve font_print_window\n\n* decomp: improve update_menu_entry_actions\n\n* decomp: improve _printf\n\n* decomp: improve _getAllRefs\n\n* decomp: improve update_menu_resource_stream\n\n* decomp: improve render_vendor_capture_pass_sequence\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve transition_load_wad\n\n* decomp: improve convert_integer_to_float\n\n* decomp: improve update_view_context\n\n* decomp: improve render_level_effects_and_screen_sprites\n\n* decomp: improve draw_cheats_menu\n\n* decomp: improve memcard_restore_data\n\n* decomp: improve draw_map_markers\n\n* decomp: improve build_indexed_resident_render_packet\n\n* decomp: improve allocate_voice_slot\n\n* decomp: improve select_world_object_resource_tables\n\n* decomp: improve append_power_of_two_textured_screen_sprite\n\n* decomp: improve initialize_gameplay_sound_system\n\n* decomp: improve update_level_gameplay_frame\n\n* decomp: improve update_preview_animation_and_attachments\n\n* decomp: improve update_mode_freeze\n\n* decomp: improve FUN_001e9b10\n\n* decomp: improve append_fullscreen_setup_strips\n\n* decomp: improve project_graphics_bounds\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve draw_map_overlay\n\n* decomp: improve draw_dialog_text\n\n* decomp: improve render_vendor_buy_label_pass\n\n* decomp: improve sound_update\n\n* decomp: improve signal_native_cd_delay_alarm\n\n* decomp: improve WriteDmaChannel\n\n* decomp: improve fast_subtract_rotations\n\n* decomp: improve hud_send_resident_bank\n\n* decomp: improve initialize_graphics_buffer_descriptors\n\n* decomp: improve mode_freeze_init\n\n* decomp: improve update_menu_preview_pose_and_attachments\n\n* decomp: improve submit_graphics_setup_command_stream\n\n* decomp: improve project_graphics_bounds_float\n\n* decomp: improve load_pif_as_psmt8_h\n\n* decomp: improve get_frame_texture\n\n* decomp: improve decode_compressed_occlusion_map\n\n* decomp: improve sound_options_menu\n\n* decomp: improve initialize_tfrag_render_data\n\n* decomp: improve render_capture_scrolling_text\n\n* decomp: improve snd_start_sound_system\n\n* decomp: improve _vfprintf_r\n\n* decomp: improve update_menu_preview_pose_and_attachments\n\n* decomp: improve append_power_of_two_textured_screen_sprite\n\n* decomp: improve submit_graphics_setup_command_stream\n\n* decomp: improve get_frame_texture\n\n* decomp: improve render_vendor_buy_label_pass\n\n* decomp: improve sceFsInit\n\n* decomp: improve snd_start_sound_system\n\n* decomp: improve allocate_voice_slot\n\n* decomp: improve printfloat\n\n* decomp: improve render_vendor_buy_label_pass\n\n* decomp: improve printfloat\n\n* decomp: improve allocate_voice_slot\n\n* decomp: improve service_level_archive_load\n\n* decomp: improve read_mpeg\n\n* decomp: improve update_item_preview_binding\n\n* decomp: improve font_print_window\n\n* decomp: improve update_menu_entry_actions\n\n* decomp: improve transition_do_transition\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve _getAllRefs\n\n* decomp: improve font_print_window\n\n* decomp: improve transition_load_wad\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve sound_update\n\n* decomp: improve transition_load_wad\n\n* decomp: improve update_mode_freeze\n\n* decomp: improve update_level_gameplay_frame\n\n* decomp: improve update_mode_freeze\n\n* decomp: improve transition_load_wad\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve _vfprintf_r\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve switch_active_camera_record\n\n* decomp: improve dma_to_spr_sync\n\n* decomp: improve load_preview_resource_bindings\n\n* decomp: improve update_resident_gameplay_state\n\n* decomp: improve switch_active_camera_record\n\n* decomp: improve _lastFrame\n\n* decomp: improve WriteDmaChannel\n\n* decomp: improve get_effect_texture\n\n* decomp: improve initialize_gameplay_sound_system\n\n* decomp: improve sceCdRead\n\n* decomp: improve render_capture_scrolling_text\n\n* decomp: improve project_graphics_bounds_float\n\n* decomp: improve append_fullscreen_clear_strips\n\n* decomp: improve project_graphics_bounds\n\n* decomp: improve set_pal_mode\n\n* decomp: improve read_mpeg\n\n* decomp: improve service_level_archive_load\n\n* decomp: improve register_object_render_class\n\n* decomp: improve register_object_render_class\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve draw_items_menu\n\n* decomp: improve font_print_window\n\n* decomp: improve font_print_window\n\n* decomp: improve transition_load_wad\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve update_level_gameplay_frame\n\n* decomp: improve transition_load_wad\n\n* decomp: improve draw_map_overlay\n\n* decomp: improve FUN_L00_002678b8\n\n* decomp: improve FUN_L00_00200228\n\n* decomp: improve FUN_L00_0024dbc0\n\n* decomp: improve set_moby_color\n\n* decomp: adapt batch 4 to upstream header layout\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":60.794277,"total_code":3502776,"matched_code":2048208,"matched_code_percent":58.47385,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4128,"matched_functions":2986,"matched_functions_percent":72.33527,"complete_code":2048208,"complete_code_percent":58.47385,"complete_data":0,"complete_data_percent":0,"total_units":434,"complete_units":215}},{"timestamp":"2026-10-06T17:06:58Z","commit_sha":"01150fd4cc60a9cba386a95a782c1d6f70fd1af9","commit_message":"refactor: clean up src (names, layout, headers, formatting) (#106)\n\n* refactor: call named boot functions by name from C\n\nRewrite about 2400 FUN_<address> call sites in 203 files (mostly the\nlevel overlays) to the function's recovered name, bound to the same\nsymbol with __asm__. rename-function-proposals.py now also rewrites\nprototypes written without extern, treats func_<ADDR> as the same\nsymbol as FUN_<addr>, keeps the FUN_ spelling where a file declares\none function with two prototypes, flags uses before the declaration,\nand treats in-place renames and INCLUDE_ASM units as applied. Six\nstale catalog source paths are fixed, and three overlay externs that\ncarried the wrong name are corrected.\n\n* refactor: call func_<ADDR> aliases by their recovered name\n\nThe rename tool now maps func_<ADDR> spellings too and leaves linker\nalias definitions alone; about 960 more call sites in 272 files take the\nfunction's name. Functions renamed in place keep their path in the\ncatalog, which undoes the path rewrites of the previous commit.\n--skip-conflicting-files leaves a file with a conflict untouched instead\nof refusing the whole run.\n\n* refactor: name 60 fun_<address> source files after their function\n\nEach of these files already defines a named function; the file, its\nunit in the linker config, configure.py's per-unit tables, the catalog\nand the overlay function table now use that name.\n\n* refactor: name the last call sites the rename tool could not rewrite\n\nSeven files had implicit calls without a prototype or externs split over\nseveral lines; they now declare their callees on one line and use the\nrecovered names. The tool reports no conflicts, so the\n--skip-conflicting-files escape hatch is gone.\n\n* refactor: sync the catalog with names already in src and use them\n\n113 catalog entries still said 'unresolved' for functions whose C\ndefinition already carries a name, and 25 pointed at paths that no\nlonger exist; seven recovered symbols named stale units. With the\ncatalog in sync, about 500 more call sites in 189 files use the names.\n\n* refactor: name five functions from what their bodies do\n\nrandom_spherical_offset, vu1_add_vif_code, read_cd_stream_sectors,\nplay_mpeg_movie and append_screen_rect_packet, with the evidence in the\ncatalog; their call sites follow.\n\n* refactor: drop 471 unused m2c type headers from include/rnc\n\nNothing in the tree includes them; they were leftovers from seeding C\nbodies.\n\n* refactor: name three type headers after the code that uses them\n\n* refactor: one MapState struct for the map screen state\n\nThe map units each declared their own partial view of D_001A00F0 (three\nstruct names, plus raw offsets in two units). include/rnc/map_state.h\nnow names the fields once: zoom, pan, current and loaded map, and the\nfive decoded-map slots with their ids and sizes.\n\n* refactor: name m2c temporaries and parameters in eight units\n\nfont_print_right*, sceCdGetError, music_start_track_{10000,30000,50000}\nand vi_buf_count read by meaning instead of register numbers.\n\n* refactor: group src/overlays/shared by subsystem\n\n139 flat <group>_<sub>_<address>.c files move to <group>/<sub>/<address>.c\n(gameplay_vendor_002e9010.c -> gameplay/vendor/002e9010.c). The 52\nunclassified files stay until their code says where they belong.\n\n* refactor: file 21 unclassified shared overlay files by their code\n\nTwenty hold moby behaviour code (create, kill, animate, randomise\nmobys) and move to shared/gameplay/entities/; one draws the sky and\nmoves to shared/rendering/sky/. Files with too little to go on stay\nunclassified.\n\n* fix: overlay gate ignores objects of moved or deleted sources\n\nverify_all globbed every object under build/overlays/c, so a moved\nsource was counted twice (old object plus new one) and the PASS total\ngrew with each move.\n\n* refactor: group include/rnc like src\n\nThe 39 flat <group>_<unit>_types.h headers move to\ninclude/rnc/<group>/<sub>/<unit>.h next to the code that uses them;\nshared ones get a name for what they hold (audio/music/music_stream_state.h,\nui/map/map_state.h, math/matrix3x4.h, ...).\n\n* fix: point 23 overlay catalogue rows at the exe unit that defines them\n\nfunctions.tsv named units that had been promoted, renamed or moved; the\nexe unit column now names the file that defines each function.\n\n* style: format src and include with clang-format\n\nWhitespace and line breaks only; both byte-exact gates pass. The rename tool now reads wrapped declarations.\n\n* fix: name overlay report units by their full grouped path","measures":{"fuzzy_match_percent":60.784664,"total_code":3502776,"matched_code":2044952,"matched_code_percent":58.380898,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4128,"matched_functions":2981,"matched_functions_percent":72.21415,"complete_code":2044952,"complete_code_percent":58.380898,"complete_data":0,"complete_data_percent":0,"total_units":434,"complete_units":214}},{"timestamp":"2026-10-06T15:11:40Z","commit_sha":"2d35acc83c6cbbf86fe8597cf3ba1892396fddb1","commit_message":"overlay: 28 new overlay functions in C (#105)\n\n* overlay: 6 migrated overlay functions\n\n* overlay: 4 migrated overlay functions\n\n* overlay: 1 migrated overlay function\n\n* overlay: 5 migrated overlay functions\n\n* overlay: 1 migrated overlay function\n\n* overlay: 1 migrated overlay function\n\n* overlay: 1 migrated overlay function\n\n* overlay: 1 migrated overlay function\n\n* overlay: 3 new overlay matches\n\n* overlay: 2 new overlay matches\n\n* overlay: 1 new overlay match\n\n* overlay: drop an inexact candidate\n\n* overlay: 1 new overlay match\n\n* overlay: 1 new overlay match\n\n* overlay: new overlay match (FUN_L13_002c13b0)","measures":{"fuzzy_match_percent":60.784096,"total_code":3502776,"matched_code":2044932,"matched_code_percent":58.380325,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4128,"matched_functions":2980,"matched_functions_percent":72.18992,"complete_code":2044932,"complete_code_percent":58.380325,"complete_data":0,"complete_data_percent":0,"total_units":433,"complete_units":213}},{"timestamp":"2026-10-06T12:14:18Z","commit_sha":"488ec66246c1373f1adf38083bbdd04b4d7ef6f1","commit_message":"overlay: 20 migrated overlay functions + 9 new matches (#104)\n\n* overlay: match fun_l06_0022a1d0 from its l01 twin\n\n* overlay: match fun_l13_002b89f8 from its l17 twin\n\n* overlay: match fun_l05_00317470 from its level sibling\n\n* overlay: match fun_l11_00311710 from its l17 twin\n\n* overlay: match fun_l08_00305270 from the l05 watcher\n\n* overlay: match fun_l14_002fba20 from the l03 watcher\n\n* overlay: match fun_l01_002ff118 from the watcher family\n\n* overlay: match fun_l14_002fefe0 from the watcher family\n\n* overlay: match fun_l08_003065d8 from the watcher family\n\n* overlay: keep unit names when inserting watcher functions\n\n* overlay: 16 migrated overlay functions\n\n* overlay: 4 migrated functions under sn\n\n* config: hand-edited settings and compiler routes at the top of configure.py\n\nMoves every per-unit compiler table, the overlay SN unit list (was\nconfig/overlays/us/sn-units.json), toolchain paths and link-layout tables\ninto one settings section above the code, with a marked boundary.\n\n* config: short section headers in configure.py\n\n* config: one header per section and single blank lines in configure.py\n\n* config: drop unused import and stale comment in configure.py","measures":{"fuzzy_match_percent":60.362488,"total_code":3502776,"matched_code":2030164,"matched_code_percent":57.958717,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4128,"matched_functions":2952,"matched_functions_percent":71.51163,"complete_code":2030164,"complete_code_percent":57.958717,"complete_data":0,"complete_data_percent":0,"total_units":433,"complete_units":212}},{"timestamp":"2026-10-06T10:52:04Z","commit_sha":"da50d2c7d3e751241317321ce6a74b47c2889b18","commit_message":"overlay: 216 migrated overlay functions + 12 new matches (#103)\n\n* decomp: split 5 functions out of text gaps\n\n* decomp: port two pause helpers from rac1-decomp\n\n* overlay: port 31 functions from rac1-decomp\n\n* overlay: match four grid-neighbour routines in L07, L11, L12, L13\n\n* overlay: match FUN_L04_002c4850\n\n* overlay: match three more ported functions (L05 shared, L08, L18)\n\n* overlay: build listed units with the SN compiler, match FUN_L05_00244a70\n\n* overlay: match the help giants of L03, L11, L12 and L15 with the SN compiler\n\n* overlay: match FUN_L06_0023b440 with the SN compiler\n\n* overlay: match 13 migrated functions with the SN compiler\n\n* overlay: match the hero state machine in nine levels with the SN compiler\n\n* overlay: match the hero state machine in L00 and L02 with the SN compiler\n\n* overlay: match the hero state setter in seven levels with the SN compiler\n\n* overlay: migrate L14 hero state setter\n\n* overlay: migrate L02 hero state setter\n\n* overlay: migrate L06 hero state setter\n\n* overlay: migrate L00 and L17 hero state setters\n\n* overlay: migrate L05 and L16 hero state setters\n\n* overlay: migrate L01 hero control routine\n\n* overlay: migrate L02 hero control routine\n\n* overlay: migrate three L12, L13 and L17 helpers\n\n* overlay: migrate four helpers in L00 and L06\n\n* overlay: migrate 19 level functions\n\n* overlay: migrate L16 vendor helper\n\n* overlay: migrate L05 and L16 hero state machines\n\n* overlay: migrate L14 vendor helper\n\n* overlay: migrate L10 vendor helper\n\n* overlay: migrate L06 and L04 helpers\n\n* overlay: drop region note from port comments\n\n* overlay: list SN-built units in JSON grouped by level\n\n* overlay: document sn-units.json and reconfigure when it changes\n\n* overlay: migrate the L18 final boss update\n\n* overlay: migrate an L15 state machine\n\n* overlay: migrate L04 and L01 state machines\n\n* overlay: migrate an L10 vendor routine\n\n* overlay: migrate an L03 state machine\n\n* overlay: migrate three level helpers\n\n* overlay: drop region notes from source comments\n\n* overlay: migrate FUN_L15_00299ca0\n\n* overlay: migrate FUN_L15_002979d8\n\n* overlay: migrate FUN_L00_002aa670\n\n* overlay: migrate FUN_L04_002d16b8\n\n* overlay: drop region notes from two port comments\n\n* overlay: migrate FUN_L16_002d04a0\n\n* overlay: migrate FUN_L16_002cddb8\n\n* overlay: migrate FUN_L16_002c9cd0\n\n* overlay: migrate FUN_L16_002cf198\n\n* overlay: migrate FUN_L16_002e6808\n\n* overlay: migrate FUN_L16_002e84e8\n\n* overlay: migrate FUN_L16_002e3fa0\n\n* overlay: migrate FUN_L16_002d2cf0\n\n* overlay: drop region notes from L16 port comments\n\n* overlay: migrate FUN_L17_002eb9a8\n\n* overlay: migrate FUN_L17_002a8da0\n\n* overlay: migrate FUN_L17_002cb310\n\n* overlay: migrate FUN_L17_002d7cf0\n\n* overlay: migrate FUN_L17_002f1940\n\n* overlay: migrate FUN_L17_002f26d0\n\n* overlay: migrate FUN_L17_002f10c8\n\n* overlay: migrate FUN_L17_002f04d0\n\n* overlay: migrate FUN_L17_002f0948\n\n* overlay: migrate FUN_L17_002ec360\n\n* overlay: migrate FUN_L18_002f8050\n\n* overlay: l18 vendor unit prep (ED70 alias)\n\n* overlay: l18 vendor unit prep (ED70 via ED6C alias)\n\n* overlay: migrate FUN_L18_002f16f0\n\n* overlay: migrate FUN_L18_002f76a0\n\n* overlay: migrate FUN_L00_002bbbc8\n\n* overlay: shared unit prep (D4 alias)\n\n* overlay: migrate FUN_L00_002bb558\n\n* overlay: migrate FUN_L14_002d7490\n\n* overlay: migrate FUN_L14_002bb310\n\n* overlay: migrate FUN_L14_002d6358\n\n* overlay: migrate FUN_L14_002aef28\n\n* overlay: migrate FUN_L14_002d64d0\n\n* overlay: migrate FUN_L02_002ee890\n\n* overlay: migrate FUN_L11_003181f0\n\n* overlay: migrate FUN_L11_0031e930\n\n* overlay: migrate FUN_L11_0031ae68\n\n* overlay: migrate FUN_L18_002fbb98\n\n* overlay: migrate FUN_L11_0030e978\n\n* overlay: migrate FUN_L11_00311be8\n\n* overlay: migrate FUN_L18_002d5488\n\n* overlay: migrate FUN_L18_002d6b58\n\n* overlay: drop region word from port comments\n\n* overlay: migrate FUN_L09_0021e8c0\n\n* overlay: migrate FUN_L09_002ee110\n\n* overlay: migrate FUN_L13_0030bb70\n\n* overlay: migrate FUN_L13_00309370\n\n* overlay: migrate FUN_L13_0030bfb0\n\n* overlay: migrate FUN_L12_00307840\n\n* overlay: migrate FUN_L12_0030be68\n\n* overlay: migrate FUN_L05_00307010\n\n* overlay: drop region word from port comments\n\n* overlay: migrate FUN_L06_002fda30\n\n* overlay: migrate FUN_L06_00302fd8\n\n* overlay: migrate FUN_L00_002b7398\n\n* overlay: migrate FUN_L00_00258830\n\n* overlay: migrate FUN_L14_002fd918\n\n* overlay: migrate FUN_L01_00308550\n\n* overlay: migrate FUN_L02_002da6c0\n\n* overlay: migrate FUN_L11_0031a1c0\n\n* overlay: migrate FUN_L10_002ea7b0\n\n* overlay: migrate FUN_L00_0024f190\n\n* overlay: migrate FUN_L07_0031eba8\n\n* overlay: migrate FUN_L01_002ff860\n\n* overlay: migrate FUN_L00_001ed358\n\n* overlay: migrate FUN_L05_002d1fd8\n\n* overlay: migrate FUN_L07_00318e98\n\n* overlay: migrate FUN_L00_0029b4d8\n\n* overlay: migrate FUN_L07_0030e998\n\n* overlay: migrate FUN_L03_0022c728\n\n* overlay: migrate FUN_L06_002f7930\n\n* overlay: migrate FUN_L00_002da058\n\n* overlay: migrate FUN_L03_002d4288\n\n* overlay: migrate FUN_L07_00270248\n\n* overlay: migrate FUN_L08_0027b450\n\n* overlay: migrate FUN_L06_002e9d10\n\n* overlay: migrate FUN_L00_00233c30\n\n* overlay: migrate FUN_L04_002ce080\n\n* overlay: migrate FUN_L00_002b56d0\n\n* overlay: migrate FUN_L15_002eac90\n\n* overlay: migrate FUN_L15_002eb108\n\n* overlay: migrate FUN_L02_002dc2c8\n\n* overlay: migrate FUN_L08_002f1548\n\n* decomp: match fun_0022f778\n\n* overlay: migrate FUN_L03_002dc478\n\n* overlay: migrate FUN_L17_002efa48\n\n* overlay: migrate FUN_L13_002e9160\n\n* overlay: migrate FUN_L17_002f0210\n\n* overlay: migrate FUN_L17_002eaae0\n\n* overlay: migrate FUN_L16_002e7e00\n\n* overlay: migrate FUN_L17_002f00a0\n\n* overlay: migrate FUN_L16_002e8b08\n\n* overlay: migrate FUN_L16_002e3770\n\n* overlay: migrate FUN_L12_002e6c48\n\n* overlay: migrate FUN_L14_002b3a20\n\n* overlay: migrate FUN_L08_003084d8\n\n* overlay: migrate FUN_L16_002d5ad0\n\n* overlay: migrate FUN_L16_002d5bc8\n\n* overlay: migrate FUN_L16_002d5db0\n\n* overlay: migrate FUN_L16_002cf738\n\n* overlay: migrate FUN_L16_002e0e28\n\n* decomp: match fun_001ed470\n\n* overlay: migrate FUN_L05_003180a0\n\n* overlay: migrate FUN_L11_0031e2f0\n\n* overlay: migrate FUN_L11_0031f150\n\n* overlay: migrate FUN_L14_002fea80\n\n* overlay: migrate FUN_L17_002020a8\n\n* overlay: migrate FUN_L06_0021d0a0\n\n* overlay: migrate FUN_L01_002efc60\n\n* decomp: match update_sky_effects","measures":{"fuzzy_match_percent":59.950127,"total_code":3502776,"matched_code":2015720,"matched_code_percent":57.546356,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4128,"matched_functions":2923,"matched_functions_percent":70.80911,"complete_code":2015720,"complete_code_percent":57.546356,"complete_data":0,"complete_data_percent":0,"total_units":433,"complete_units":209}},{"timestamp":"2026-10-06T05:21:22Z","commit_sha":"2c4452dd03f5f7ebb2868dbe073ccdb1afb27f61","commit_message":"overlay: promote FUN_L18_002dfba0 (32 B) (#102)\n\n* overlay: add scalar C candidates with retained oracles (88 B)\n\n* overlay: promote FUN_L18_002dfba0 (32 B)","measures":{"fuzzy_match_percent":32.23422,"total_code":3499624,"matched_code":1036152,"matched_code_percent":29.607525,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4123,"matched_functions":2693,"matched_functions_percent":65.31652,"complete_code":1036152,"complete_code_percent":29.607525,"complete_data":0,"complete_data_percent":0,"total_units":433,"complete_units":165}},{"timestamp":"2026-10-06T03:57:44Z","commit_sha":"59714becdd113f2fc685b708fde17b39fa7e5352","commit_message":"decomp: decompilierizer batch 3 (#101)\n\n* decomp: improve convert_integer_to_float\n\n* decomp: improve clear_u64_value\n\n* decomp: improve kputchar\n\n* decomp: improve FUN_0011b980\n\n* decomp: improve SignExtendPackedValue\n\n* decomp: improve scale_game_frames\n\n* decomp: improve copy_matrix3x4\n\n* decomp: improve fast_difference_between_rotations\n\n* decomp: improve func_00207580\n\n* decomp: improve WriteDmaChannelRegisters\n\n* decomp: improve _type2id\n\n* decomp: improve fast_add_rotations\n\n* decomp: improve fast_normalize_angle\n\n* decomp: improve ftoi\n\n* decomp: improve fast_subtract_rotations\n\n* decomp: improve update_visible_resident_objects\n\n* decomp: improve set_moby_animation\n\n* decomp: improve sceDbcCreateSocket\n\n* decomp: improve cmd_sem_init\n\n* decomp: improve LoadDefaultMpegQuantizerMatrix\n\n* decomp: improve initialize_graphics_buffer_descriptors\n\n* decomp: improve printfloat\n\n* decomp: improve music_transition\n\n* decomp: improve hud_send_resident_bank\n\n* decomp: improve append_power_of_two_textured_screen_sprite\n\n* decomp: improve get_effect_texture\n\n* decomp: improve initialize_gameplay_sound_system\n\n* decomp: improve mode_freeze_init\n\n* decomp: improve update_menu_preview_pose_and_attachments\n\n* decomp: improve append_fullscreen_setup_strips\n\n* decomp: improve configure_graphics_projection\n\n* decomp: improve sceCdRead\n\n* decomp: improve sceFsInit\n\n* decomp: improve advance_accelerated_scalar\n\n* decomp: improve native_cd_disk_ready\n\n* decomp: improve load_pif_as_psmt8_h\n\n* decomp: improve sceSifCallRpc\n\n* decomp: improve append_fullscreen_clear_strips\n\n* decomp: improve _doMC\n\n* decomp: improve project_graphics_bounds\n\n* decomp: improve project_graphics_bounds_float\n\n* decomp: improve submit_graphics_setup_command_stream\n\n* decomp: improve render_capture_scrolling_text\n\n* decomp: improve decode_compressed_occlusion_map\n\n* decomp: improve memcard_restore_data\n\n* decomp: improve get_frame_texture\n\n* decomp: improve render_vendor_buy_label_pass\n\n* decomp: improve draw_map_markers\n\n* decomp: improve snd_start_sound_system\n\n* decomp: improve build_indexed_resident_render_packet\n\n* decomp: improve draw_cheats_menu\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve _csc_storeRefImage\n\n* decomp: improve UpdateMpegReferenceImages\n\n* decomp: improve select_world_object_resource_tables\n\n* decomp: improve allocate_voice_slot\n\n* decomp: improve sample_surface_height_map\n\n* decomp: improve sceCdInit\n\n* decomp: improve sound_options_menu\n\n* decomp: improve FUN_00226b08\n\n* decomp: improve initialize_tfrag_render_data\n\n* decomp: improve draw_localized_three_option_menu\n\n* decomp: improve set_pal_mode\n\n* decomp: improve draw_checking_memory_card_data_menu\n\n* decomp: improve read_mpeg\n\n* decomp: improve vi_buf_restart_dma\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve service_level_archive_load\n\n* decomp: improve update_gameplay_frame\n\n* decomp: improve draw_sound_menu\n\n* decomp: improve update_camera_tracking_state\n\n* decomp: improve _sceFs_Rcv_Intr\n\n* decomp: improve update_streamed_moby_animation\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve initialize_audio_system\n\n* decomp: improve register_object_render_class\n\n* decomp: improve update_item_preview_binding\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":32.233303,"total_code":3499624,"matched_code":1036120,"matched_code_percent":29.60661,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4123,"matched_functions":2692,"matched_functions_percent":65.29226,"complete_code":1036120,"complete_code_percent":29.60661,"complete_data":0,"complete_data_percent":0,"total_units":433,"complete_units":165}},{"timestamp":"2026-10-05T19:23:09Z","commit_sha":"496ee77e879a9589a2b377f394d538c39b4b9662","commit_message":"decomp: compilierizer batch 2 (#100)\n\n* decomp: improve scale_game_frames\n\n* decomp: improve fast_normalize_angle\n\n* decomp: improve fast_subtract_rotations\n\n* decomp: improve fast_add_rotations\n\n* decomp: improve dma_to_spr_sync\n\n* decomp: improve music_transition\n\n* decomp: improve update_visible_resident_objects\n\n* decomp: improve configure_graphics_projection\n\n* decomp: improve update_camera_environment_from_regions\n\n* decomp: improve initialize_graphics_buffer_descriptors\n\n* decomp: improve initialize_gameplay_sound_system\n\n* decomp: improve hud_send_resident_bank\n\n* decomp: improve advance_accelerated_scalar\n\n* decomp: improve mode_freeze_init\n\n* decomp: improve append_power_of_two_textured_screen_sprite\n\n* decomp: improve append_fullscreen_setup_strips\n\n* decomp: improve load_pif_as_psmt8_h\n\n* decomp: improve FUN_00121190\n\n* decomp: improve project_graphics_bounds_float\n\n* decomp: improve append_fullscreen_clear_strips\n\n* decomp: improve submit_graphics_setup_command_stream\n\n* decomp: improve get_frame_texture\n\n* decomp: improve snd_start_sound_system\n\n* decomp: improve project_graphics_bounds\n\n* decomp: improve render_capture_scrolling_text\n\n* decomp: improve decode_compressed_occlusion_map\n\n* decomp: improve memcard_restore_data\n\n* decomp: improve render_vendor_buy_label_pass\n\n* decomp: improve draw_map_markers\n\n* decomp: improve draw_cheats_menu\n\n* decomp: improve build_indexed_resident_render_packet\n\n* decomp: improve allocate_voice_slot\n\n* decomp: improve select_world_object_resource_tables\n\n* decomp: improve update_menu_preview_pose_and_attachments\n\n* decomp: improve initialize_audio_system\n\n* decomp: improve loading_data_menu\n\n* decomp: improve sample_surface_height_map\n\n* decomp: improve sound_options_menu\n\n* decomp: improve draw_localized_three_option_menu\n\n* decomp: improve initialize_tfrag_render_data\n\n* decomp: improve FUN_00226b08\n\n* decomp: improve set_pal_mode\n\n* decomp: improve switch_active_camera_record\n\n* decomp: improve draw_checking_memory_card_data_menu\n\n* decomp: improve read_mpeg\n\n* decomp: improve append_billboard_batch\n\n* decomp: improve update_gameplay_frame\n\n* decomp: improve update_camera_tracking_state\n\n* decomp: improve update_item_preview_binding\n\n* decomp: improve update_streamed_moby_animation\n\n* decomp: improve service_level_archive_load\n\n* decomp: improve draw_sound_menu\n\n* decomp: improve render_level_frame\n\n* decomp: improve register_object_render_class\n\n* decomp: improve vi_buf_restart_dma\n\n* decomp: improve get_effect_texture\n\n* decomp: improve append_rotated_sprite_quad\n\n* decomp: improve upload_mip_texture\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve startlevel\n\n* decomp: improve music_update\n\n* decomp: improve render_vendor_capture_texture_overlays_pass\n\n* decomp: improve draw_level_selection_map\n\n* decomp: improve update_sky_effects\n\n* decomp: improve transition_do_transition\n\n* decomp: improve font_print_window\n\n* decomp: improve update_menu_grid_selection\n\n* decomp: improve draw_items_menu\n\n* decomp: improve update_menu_resource_stream\n\n* decomp: improve render_localized_ui_entry_list\n\n* decomp: improve render_environment_mapped_object\n\n* decomp: improve update_menu_entry_actions\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve update_view_context\n\n* decomp: improve render_level_effects_and_screen_sprites\n\n* decomp: improve transition_load_wad\n\n* decomp: improve update_mode_freeze\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve FUN_001e9b10\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve update_preview_animation_and_attachments\n\n* decomp: improve sound_update\n\n* decomp: improve update_level_gameplay_frame\n\n* decomp: improve draw_dialog_text\n\n* decomp: improve draw_map_overlay\n\n* decomp: improve load_hand_gadget\n\n* decomp: improve convert_integer_to_float\n\n* decomp: improve WriteDmaChannelRegisters\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve _printf\n\n* decomp: improve render_vendor_capture_pass_sequence\n\n* decomp: improve LoadDefaultMpegQuantizerMatrix\n\n* decomp: improve UpdateMpegReferenceImages\n\n* decomp: improve sceFsInit\n\n* decomp: improve printfloat\n\n* decomp: improve sceCdRead\n\n* decomp: improve sceTtyWrite\n\n* decomp: improve clear_u64_value\n\n* decomp: improve _doMC\n\n* decomp: improve _sceFs_Rcv_Intr\n\n* decomp: improve sceCdInit\n\n* decomp: improve sceMpegDemuxPssRing\n\n* decomp: improve _getRef0\n\n* decomp: improve _getAllRefs\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve initialize_level_runtime\n\n* decomp: improve _csc_storeRefImage\n\n* decomp: expose resident SDK callbacks for C recovery\n\n* decomp: improve WriteDmaChannel\n\n* decomp: improve report_mpeg_picture_spatial_scalable_unsupported\n\n* decomp: improve suspend_mpeg_decoder_ipu_dma\n\n* decomp: improve signal_native_cd_delay_alarm\n\n* decomp: improve report_mpeg_picture_temporal_scalable_unsupported\n\n* decomp: restore delay alarm oracle\n\n* decomp: improve FUN_00123d10\n\n* decomp: improve suspend_ipu_dma_state\n\n* decomp: improve handle_sif_rpc_call\n\n* decomp: improve dispatch_native_cd_power_event\n\n* decomp: improve rebuild_configured_text_label_list\n\n* decomp: improve prepare_resident_class_render_data\n\n* decomp: improve process_native_cd_read_completion\n\n* decomp: improve report_unknown_mpeg_extension\n\n* decomp: improve update_item_preview_transform\n\n* decomp: improve report_mpeg_sequence_scalable_unsupported\n\n* decomp: improve resume_mpeg_decoder_ipu_dma\n\n* decomp: improve fast_difference_between_rotations\n\n* decomp: improve update_resident_gameplay_state\n\n* decomp: prepare reentrant formatter and preserve CD callback alias\n\n* decomp: improve fast_subtract_rotations\n\n* decomp: improve sceTtyWrite\n\n* decomp: improve fast_normalize_angle\n\n* decomp: improve printfloat\n\n* decomp: improve initialize_graphics_buffer_descriptors\n\n* decomp: improve hud_send_resident_bank\n\n* decomp: improve configure_graphics_projection\n\n* decomp: improve hud_send_resident_bank\n\n* decomp: improve configure_graphics_projection\n\n* decomp: improve sceCdRead\n\n* decomp: improve initialize_graphics_buffer_descriptors\n\n* decomp: improve project_graphics_bounds\n\n* decomp: improve sceCdRead\n\n* decomp: improve render_capture_scrolling_text\n\n* decomp: improve get_frame_texture\n\n* decomp: improve build_indexed_resident_render_packet\n\n* decomp: improve project_graphics_bounds\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve get_frame_texture\n\n* decomp: improve initialize_tfrag_render_data\n\n* decomp: improve loading_data_menu\n\n* decomp: improve sceMpegDemuxPssRing\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve FUN_00226b08\n\n* decomp: improve set_pal_mode\n\n* decomp: improve loading_data_menu\n\n* decomp: improve read_mpeg\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve FUN_00226b08\n\n* decomp: improve update_gameplay_frame\n\n* decomp: improve render_level_frame\n\n* decomp: improve set_pal_mode\n\n* decomp: improve read_mpeg\n\n* decomp: improve service_level_archive_load\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve update_item_preview_binding\n\n* decomp: improve update_gameplay_frame\n\n* decomp: improve upload_mip_texture\n\n* decomp: improve _getRef0\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve service_level_archive_load\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve render_environment_mapped_object\n\n* decomp: improve render_localized_ui_entry_list\n\n* decomp: improve update_item_preview_binding\n\n* decomp: improve font_print_window\n\n* decomp: improve _getRef0\n\n* decomp: improve render_vendor_capture_pass_sequence\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve update_view_context\n\n* decomp: improve build_resident_indexed_texture_warp_meshes\n\n* decomp: improve font_print_window\n\n* decomp: improve render_level_effects_and_screen_sprites\n\n* decomp: improve render_localized_ui_entry_list\n\n* decomp: improve transition_load_wad\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve update_view_context\n\n* decomp: improve render_level_effects_and_screen_sprites\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve sound_update\n\n* decomp: improve sound_update\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: prepare sceVu0RotMatrixZ for C recovery\n\n* decomp: improve sceVu0RotMatrixZ\n\n* decomp: expose resident value-band predicate for C recovery\n\n* decomp: improve func_00207580\n\n* decomp: improve initialize_level_runtime\n\n* decomp: guard pending Resident C for plain-C recovery\n\n* decomp: improve _outputFrame\n\n* decomp: improve kputchar\n\n* decomp: improve cmd_sem_init\n\n* decomp: improve ftoi\n\n* decomp: improve sceDbcCreateSocket\n\n* decomp: improve SignExtendPackedValue\n\n* decomp: improve scePad2SetButtonOrder\n\n* decomp: improve _type2id\n\n* decomp: improve set_moby_animation\n\n* decomp: improve load_preview_resource_bindings\n\n* decomp: improve sceSifCallRpc\n\n* decomp: improve _lastFrame\n\n* decomp: improve invoke_sif_file_command_callback\n\n* decomp: improve kputchar\n\n* decomp: improve WriteDmaChannel\n\n* decomp: improve fast_difference_between_rotations\n\n* decomp: improve update_visible_resident_objects\n\n* decomp: improve fast_subtract_rotations\n\n* decomp: improve cmd_sem_init\n\n* decomp: improve ftoi\n\n* decomp: improve scePad2SetButtonOrder\n\n* decomp: improve WriteDmaChannel\n\n* decomp: improve get_effect_texture\n\n* decomp: improve scePad2SetButtonOrder\n\n* decomp: improve update_camera_environment_from_regions\n\n* decomp: improve initialize_gameplay_sound_system\n\n* decomp: improve initialize_graphics_buffer_descriptors\n\n* decomp: improve ftoi\n\n* decomp: improve sceCdRead\n\n* decomp: improve project_graphics_bounds_float\n\n* decomp: improve _doMC\n\n* decomp: improve draw_map_markers\n\n* decomp: improve sceSifInitCmd\n\n* decomp: improve sceMpegDemuxPssRing\n\n* decomp: improve _doMC\n\n* decomp: improve sound_options_menu\n\n* decomp: improve prepare_loading_slide_textures\n\n* decomp: improve read_mpeg\n\n* decomp: improve append_billboard_batch\n\n* decomp: improve _sceFs_Rcv_Intr\n\n* decomp: improve register_object_render_class\n\n* decomp: improve _sequenceHeader\n\n* decomp: improve draw_items_menu\n\n* decomp: improve _sceFs_Rcv_Intr\n\n* decomp: improve register_shrub_render_class\n\n* decomp: improve register_object_render_class\n\n* decomp: improve update_view_context\n\n* decomp: improve render_configured_text_label\n\n* decomp: improve update_level_gameplay_frame\n\n* decomp: improve sound_update\n\n* decomp: improve setup_fs_aa_buffer\n\n* decomp: improve draw_map_overlay\n\n* decomp: improve draw_map_overlay\n\n---------\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":32.23279,"total_code":3499624,"matched_code":1035444,"matched_code_percent":29.587294,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4123,"matched_functions":2691,"matched_functions_percent":65.268005,"complete_code":1035444,"complete_code_percent":29.587294,"complete_data":0,"complete_data_percent":0,"total_units":433,"complete_units":164}},{"timestamp":"2026-10-05T17:01:16Z","commit_sha":"59f71a6832cd0e445f36c8880f7d882f8d03f295","commit_message":"ci: rebuild the website after publishing progress (#99)","measures":{"fuzzy_match_percent":32.262283,"total_code":3493132,"matched_code":1023156,"matched_code_percent":29.290504,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4107,"matched_functions":2665,"matched_functions_percent":64.88921,"complete_code":1023156,"complete_code_percent":29.290504,"complete_data":0,"complete_data_percent":0,"total_units":432,"complete_units":163}},{"timestamp":"2026-10-05T16:46:55Z","commit_sha":"b974aa11a61ddc7114c45f6e607f6cb4941b6cf6","commit_message":"overlay: match per-level help giants (#98)\n\n* overlay: match help giant FUN_L00_00217970\n\n* overlay: match help giant FUN_L17_00214760\n\n* overlay: match help giants FUN_L18_0021eac8 and FUN_L08_002284e0\n\n* overlay: match help giants FUN_L06_0022e020 and FUN_L14_00228cd0\n\n* overlay: match help giant FUN_L16_00214598","measures":{"fuzzy_match_percent":32.262283,"total_code":3493132,"matched_code":1023156,"matched_code_percent":29.290504,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4107,"matched_functions":2665,"matched_functions_percent":64.88921,"complete_code":1023156,"complete_code_percent":29.290504,"complete_data":0,"complete_data_percent":0,"total_units":432,"complete_units":163}},{"timestamp":"2026-10-05T09:13:07Z","commit_sha":"c653f64228a51aff94fbaf991419b09e9fa2c1e6","commit_message":"docs: point links to the lombyte-project organization (#97)\n\n* docs: point links to the lombyte-project organization\n\n* docs: point rac1-decomp links to OpenRAC","measures":{"fuzzy_match_percent":25.781796,"total_code":3493132,"matched_code":796784,"matched_code_percent":22.810017,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4107,"matched_functions":2658,"matched_functions_percent":64.71877,"complete_code":796784,"complete_code_percent":22.810017,"complete_data":0,"complete_data_percent":0,"total_units":432,"complete_units":157}},{"timestamp":"2026-10-05T08:48:58Z","commit_sha":"689290fa6eac79faf6acede7977ce50534c72ad2","commit_message":"chore: move the website to lombyte-project.github.io (#96)","measures":{"fuzzy_match_percent":25.781796,"total_code":3493132,"matched_code":796784,"matched_code_percent":22.810017,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4107,"matched_functions":2658,"matched_functions_percent":64.71877,"complete_code":796784,"complete_code_percent":22.810017,"complete_data":0,"complete_data_percent":0,"total_units":432,"complete_units":157}},{"timestamp":"2026-10-05T07:45:11Z","commit_sha":"dac27dbba5b6da4296f8baebffd14b6be4848acf","commit_message":"docs: GitHub Pages website (#95)\n\n* docs: add GitHub Pages site with project status and SEO metadata\n\n* docs: reuse README assets on the Pages site\n\n* docs: add commits bar, Discord link and generic trademark notice to the Pages site\n\n* docs: hero background, black theme, interactive stat tiles and clearer commits bar\n\n* docs: map-coloured stat tiles and About cards on the Pages site\n\n* docs: SEO pass on the Pages site and website link in README\n\n* docs: keep website sources on the pages branch\n\n* docs: drop website badge from README\n\n* docs: full main history for the commit count","measures":{"fuzzy_match_percent":25.781796,"total_code":3493132,"matched_code":796784,"matched_code_percent":22.810017,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4107,"matched_functions":2658,"matched_functions_percent":64.71877,"complete_code":796784,"complete_code_percent":22.810017,"complete_data":0,"complete_data_percent":0,"total_units":432,"complete_units":157}},{"timestamp":"2026-10-05T04:02:56Z","commit_sha":"15d19a150b30d34429c80a48223f965380be80c9","commit_message":"decomp: Veldin1 and level overlays w22 (51 exact) (#94)","measures":{"fuzzy_match_percent":25.781796,"total_code":3493132,"matched_code":796784,"matched_code_percent":22.810017,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4107,"matched_functions":2658,"matched_functions_percent":64.71877,"complete_code":796784,"complete_code_percent":22.810017,"complete_data":0,"complete_data_percent":0,"total_units":432,"complete_units":157}},{"timestamp":"2026-10-05T01:37:21Z","commit_sha":"e1db4cd6b48282a75420f3e69ac7f2cb699523eb","commit_message":"decomp: improve resident executable matching (#93)","measures":{"fuzzy_match_percent":24.654442,"total_code":3493132,"matched_code":757404,"matched_code_percent":21.682661,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4107,"matched_functions":2611,"matched_functions_percent":63.574387,"complete_code":757404,"complete_code_percent":21.682661,"complete_data":0,"complete_data_percent":0,"total_units":432,"complete_units":155}},{"timestamp":"2026-10-04T18:39:07Z","commit_sha":"fb082a56db5af279d3bc0f1e6220b6f49d5f2209","commit_message":"decomp: Veldin shared w21 (overlay intentional asm, 5 exact) (#92)","measures":{"fuzzy_match_percent":24.653406,"total_code":3493132,"matched_code":755908,"matched_code_percent":21.639835,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4107,"matched_functions":2608,"matched_functions_percent":63.50134,"complete_code":755908,"complete_code_percent":21.639835,"complete_data":0,"complete_data_percent":0,"total_units":432,"complete_units":155}},{"timestamp":"2026-10-04T18:11:01Z","commit_sha":"f0747c237eeb3e6f7189301e56f63a945e3ada23","commit_message":"docs: revise AI project involvement description in README\n\nUpdated language regarding AI involvement in the project.","measures":{"fuzzy_match_percent":24.32485,"total_code":3520104,"matched_code":750992,"matched_code_percent":21.33437,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4157,"matched_functions":2603,"matched_functions_percent":62.61727,"complete_code":750992,"complete_code_percent":21.33437,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":153}},{"timestamp":"2026-10-04T15:33:36Z","commit_sha":"454fce0714f8131653160fe02c375f0e327f4e3f","commit_message":"decomp: Veldin shared w20 (catalogue tail fix, 20 exact, RC1 alignment) (#91)\n\n* overlay: 3 exact shared functions from the level-00 sweep (1088 B)\n\n  L10 0024c7f0 36, L06 002f38c8 524, L01 003087e0 528\n\nWave 25/26 of the shared-function sweep, promoted with the byte proof\n(receipts in Lombyte-Tools/.decomp/overlays.json). Shared level code\nC_EXACT 29.39 % -> 29.44 %, level overlays 16.34 % -> 16.37 %,\nheadline 21.18 % -> 21.26 %; Level 00 stays 100 %.\nverify-baseline.sh: PASS (reconstructed boot ELF matches retail).\n\nWhat made them: section(\".sdata\") on a `la`-address array forces the whole\nlui+addiu pair ahead of the frame store; the four colour-mask bytes\nextracted before the calls with one shared 0xFF default and retail's\nsaved-register allocation; qcopy plus a local u8* base pins %hi, with the\nfloat literals written from their exact bit patterns.\n\nThe rest of the wave's rows are the hard tail: from-scratch 2-40 KB\nfunctions with no seed (no twin, PAL twin a stub), VU0/MMI handwritten\nrows, and register-allocation/scheduler walls; their region maps and\nmeasured residuals are banked in Lombyte-Tools for the next wave.\n\n* config: refresh the overlay catalogue against the renamed and promoted units\n\n`decomp overlays catalogue` after the upstream renames and promotions: the\n30 changed rows follow the new source paths (font_print_wrapped,\nsave_card_state_*), and the rows that upstream promoted on the executable\nside move from `shared` overlay rows to their `exe` names and sizes.\nReport totals move with it (overlay total 3 180 524 -> 3 179 596 B).\n\n* overlay: 2 exact level-00 shared functions (1004 B)\n\n  L00 002050c0 76, L00 0020cf58 928\n\nWave 28, promoted with the byte proof (receipts in\nLombyte-Tools/.decomp/overlays.json). Shared level code C_EXACT\n29.44 % -> 29.53 %, level overlays 16.37 % -> 16.40 %, headline\n21.26 % -> 21.29 %; Level 00 stays 100 %. verify-baseline.sh: PASS.\n\nWhat made them: the parameter reused as the accumulator\n(`if (n >= 2) n = 1;` keeps n in $a0 and gives retail's movn), and\nD_0015ED84 declared a plain extern s32 — the section(\".data\") attribute\nmade gcc split the address into two registers where retail reuses one.\n\nThe rest of the wave's rows are compiler ties: the closest 55 level-00\nrows (<= 15 differing words) were worked with the full lever catalogue\nand a 10-minute random permuter run each; they are allocno/scheduler\nties no C spelling moves, and their measurements are banked in\nLombyte-Tools.\n\n* overlay: drop overlay C of the rows the catalogue now maps to executable functions\n\nThe catalogue refresh maps eight shared rows (the save-card state handlers,\nFUN_0021ca60, FUN_00225588) to their executable functions, which are already\nC on the executable side. Their overlay copies were still defined under the\nold FUN_L00_ names and failed `make overlays` with LINK; the stub of\nFUN_L00_0024adb0 (now FUN_002089d0) goes too.\n\n* overlay: fold the 14 hand-confirmed tail rows back into their functions\n\nEvery confirmed start was the tail of the row before it: that row branches\ninto it and both share the final jr $ra. The tails compiled alone, so the\npromoted C looked like evidence, but no C function can branch into another.\nWithout them the catalogue merges each pair; seven of the merged L00 menu\nand ring-buffer rows are copies of executable functions that are already C\n(FUN_001fd6e0, FUN_00206a90, FUN_00206b10, FUN_002074b0, FUN_00207720,\nFUN_002077a0, FUN_00207880), and the overlay C of their halves goes. The\ncatalogue now also follows bc1t/bc1f, which folds three more tails\n(FUN_L05_003294c0, FUN_L08_00211b08, FUN_L10_002d7b18).\n\nEight merged rows are exact as one function: FUN_L00_00263b38,\nFUN_L00_002e84f0, FUN_L03_002dcb30, FUN_L04_002e1768, FUN_L05_002551d0,\nFUN_L05_003294c0, FUN_L10_002d7b18, FUN_L14_003061d8. FUN_L08_00211b08 is\nhand-written and stays a stub.\n\n* decomp: align with bordplate/RC1 (readBufEndPut and 11 recovered names)\n\nFUN_0023b990 (68 B, the ring buffer commit after a put) was inside the\ntext gap after read_buf_begin_put; cut out and exact. Its overlay copy\nFUN_L00_002ef300 is now the executable function in the catalogue, so its\noverlay C goes.\n\nEleven fun_<addr> units take the names RC1 recovered, with the original\nsymbol as an alias: draw_screen_effect, font_queue_vu_state,\ndraw_debug_font, set_pause_action_list, pause_stage_sprite_lists,\nvu1_gs_regs_alt, vu1_gs_regs_font, setup_view_context,\nmpeg_restart_video_dma, and the two sound_GetFade overloads (files named\nafter their existing C names, calculate_voice_distance_volume and\ncalculate_voice_volume; their configure.py entries follow the path).\n\n* overlay: 5 exact level-00 shared functions (928 B)\n\nFUN_L00_002e88c8, FUN_L00_002df4a8, FUN_L00_0025a420, FUN_L00_00239630 and\nFUN_L00_002668a0 were 1-5 words off; the overlay permuter found the\nspellings.\n\n* overlay: exact FUN_L00_002725d8 (252 B, permuter lead)\n\n* overlay: drop confirmed-starts.tsv\n\nIt held only tail rows; the catalogue rule finds uncalled functions by shape,\nand a start the rule misses is fixed in the rule. Catalogue unchanged.","measures":{"fuzzy_match_percent":24.32485,"total_code":3520104,"matched_code":750992,"matched_code_percent":21.33437,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4157,"matched_functions":2603,"matched_functions_percent":62.61727,"complete_code":750992,"complete_code_percent":21.33437,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":153}},{"timestamp":"2026-10-04T09:35:09Z","commit_sha":"e82305e6e01423428b814d397b2a687aa44f9253","commit_message":"overlay: promote FUN_L17_002f2e78 and FUN_L14_003014e0 (396 B) (#90)\n\n* overlay: promote FUN_L17_002f2e78 (160 B)\n\nExact C for the Level 17 moby update, ported from the PAL decomp (rac1-decomp,\nfunc_L17_002F49B8) with names translated to the US level program.\nmake overlays: PASS: all 1539 overlay functions in C match retail.\n\n* overlay: promote FUN_L14_003014e0 (236 B)\n\nExact C for the Level 14 spawner, ported from the PAL decomp (rac1-decomp,\nfunc_L14_00302968) with names translated to the US level program.\nmake overlays: PASS: all 1539 overlay functions in C match retail.","measures":{"fuzzy_match_percent":24.236446,"total_code":3521820,"matched_code":748296,"matched_code_percent":21.247423,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2605,"matched_functions_percent":62.157,"complete_code":748296,"complete_code_percent":21.247423,"complete_data":0,"complete_data_percent":0,"total_units":442,"complete_units":154}},{"timestamp":"2026-10-04T08:39:50Z","commit_sha":"5bffaa3b89748f82ed87fbd005d3778ba09f68ad","commit_message":"refactor: move rebuild-iso.py to scripts/, drop verify-overlays wrapper (#89)\n\n* refactor: move rebuild-iso.py to scripts/, drop verify-overlays wrapper\n\n* refactor: drop normalize-pending-bodies.py (nothing left to normalize)\n\n* refactor: drop rename-function-proposals.py (renames applied)\n\n* refactor: keep rename-function-proposals.py (used for new names)","measures":{"fuzzy_match_percent":24.225203,"total_code":3521820,"matched_code":747900,"matched_code_percent":21.23618,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2603,"matched_functions_percent":62.109283,"complete_code":747900,"complete_code_percent":21.23618,"complete_data":0,"complete_data_percent":0,"total_units":442,"complete_units":154}},{"timestamp":"2026-10-04T06:11:20Z","commit_sha":"2eb70f2282632f3ef160b14787265c70d02984ad","commit_message":"decomp: improve resident audio, menus and previews (#88)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":24.225203,"total_code":3521820,"matched_code":747900,"matched_code_percent":21.23618,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2603,"matched_functions_percent":62.109283,"complete_code":747900,"complete_code_percent":21.23618,"complete_data":0,"complete_data_percent":0,"total_units":442,"complete_units":154}},{"timestamp":"2026-10-04T05:37:02Z","commit_sha":"314190859098f3fcbdf095bb82f115a4bea3d0f4","commit_message":"overlay: contribute to the level overlays from the public repo alone (#85)\n\n* overlay: contribute to the level overlays from the public repo alone\n\nOverlay work needed the private tooling for the records, the listings and\nthe byte proof. The public repo now does all of it, with the same loop as\nthe boot executable:\n\n- scripts/overlay-extract.py cuts the level records from your own disc\n  image and generates config/us/overlays/asm (both gitignored); setup.sh\n  --iso runs it after make elf. Output is identical to the tooling's.\n- check-unit.py FUN_LNN_xxxxxxxx stages the C under the NON_MATCHING guard,\n  compiles it on the game route and proves the placed bytes\n  (scripts/overlay_proof.py).\n- list-functions.py --overlays lists pending overlay functions.\n- make overlays builds every file and proves every function in C (PASS).\n- A test fails if anything cut from the disc is tracked.\n\nThe new gate found 20 functions in C that were not byte-exact in place:\n15 named another level's copy of a gp-relative variable (now aliased to\ntheir own level's) and one called a renamed address (restored); 5 differ in\ncontext and go back under the guard with their C kept.\n\nCONTRIBUTING and docs/overlays.md are rewritten shorter.\n\n* overlay: make the five context-broken functions exact again\n\nFUN_L00_0023a7a8, FUN_L00_002e89b0 and FUN_L15_002cbd88 were exact alone\nbut not in their file: an earlier sda declaration of the same symbol made\nthe assembler use $gp where retail uses lui/lw. Each now starts its own file\n(ui_text_0023a7a8.c, gameplay_vendor_002e89b0.c, unclassified_002cbd88.c),\nwhich is where retail's translation unit evidently changed.\nFUN_L14_003135b8 and FUN_L14_003167e0 read their globals as .data (lui/lw\ninto another register), as retail does.\n\nAlso: the gp-variable aliases use the usual _d suffix, verify-overlays\nreconfigures every run, setup.sh says why --no-build skips the overlays.","measures":{"fuzzy_match_percent":24.225203,"total_code":3521820,"matched_code":747900,"matched_code_percent":21.23618,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2603,"matched_functions_percent":62.109283,"complete_code":747900,"complete_code_percent":21.23618,"complete_data":0,"complete_data_percent":0,"total_units":442,"complete_units":154}},{"timestamp":"2026-10-04T05:27:27Z","commit_sha":"540cf07f2442d56ba8e3fb67902311b5023267a6","commit_message":"decomp: improve resident UI, audio and map functions (#86)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":24.225203,"total_code":3521820,"matched_code":747900,"matched_code_percent":21.23618,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2603,"matched_functions_percent":62.109283,"complete_code":747900,"complete_code_percent":21.23618,"complete_data":0,"complete_data_percent":0,"total_units":439,"complete_units":151}},{"timestamp":"2026-10-04T05:18:20Z","commit_sha":"e718867219098c6d145acac89ed51d6a2ccd3059","commit_message":"decomp: recover Blackwater hoverboard host easter egg (#87)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":24.225203,"total_code":3521820,"matched_code":747636,"matched_code_percent":21.228683,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2602,"matched_functions_percent":62.085423,"complete_code":747636,"complete_code_percent":21.228683,"complete_data":0,"complete_data_percent":0,"total_units":439,"complete_units":151}},{"timestamp":"2026-10-03T22:22:50Z","commit_sha":"b2370c2d16533c747e89c29df576d5e4269b40cd","commit_message":"overlay: 52 exact Veldin shared and level functions (#84)","measures":{"fuzzy_match_percent":24.225203,"total_code":3521820,"matched_code":747636,"matched_code_percent":21.228683,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2602,"matched_functions_percent":62.085423,"complete_code":747636,"complete_code_percent":21.228683,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":151}},{"timestamp":"2026-10-03T18:47:05Z","commit_sha":"64543183305bb5bcda0b40235b4a782a5218833b","commit_message":"decomp: improve resident frame, camera and effects matching (#83)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":23.202549,"total_code":3521820,"matched_code":711620,"matched_code_percent":20.20603,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2550,"matched_functions_percent":60.844666,"complete_code":711620,"complete_code_percent":20.20603,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":148}},{"timestamp":"2026-10-03T17:22:01Z","commit_sha":"7ab7c9883c499769cdff290cc702a50c8347cbf8","commit_message":"fix: logo with better colors (#82)","measures":{"fuzzy_match_percent":23.202549,"total_code":3521820,"matched_code":711620,"matched_code_percent":20.20603,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2550,"matched_functions_percent":60.844666,"complete_code":711620,"complete_code_percent":20.20603,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":148}},{"timestamp":"2026-10-03T17:10:38Z","commit_sha":"4576e80f1c7c9f69f766a9b69bdd04c883002c12","commit_message":"docs: new logo and README header (#81)\n\n* docs: new logo and README header\n\n* docs: drop h1 underline in README header\n\n* docs: h1-sized README title without underline","measures":{"fuzzy_match_percent":23.202549,"total_code":3521820,"matched_code":711620,"matched_code_percent":20.20603,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2550,"matched_functions_percent":60.844666,"complete_code":711620,"complete_code_percent":20.20603,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":148}},{"timestamp":"2026-10-03T16:06:08Z","commit_sha":"6fd0bce3be36c1ac9c2255521f2b9b713ff2b42d","commit_message":"decomp: recover resident capture and sprite functions (#80)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":23.202549,"total_code":3521820,"matched_code":711620,"matched_code_percent":20.20603,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2550,"matched_functions_percent":60.844666,"complete_code":711620,"complete_code_percent":20.20603,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":148}},{"timestamp":"2026-10-03T14:45:02Z","commit_sha":"5cd628a71ce9a9994c832e9d0e9df0a06ce9bdc4","commit_message":"fix: name progress units after their non-static function (#79)\n\nUnits that open with static inline helpers were reported under the\nhelper's name, so two SDK units both showed up as IsNaN and decomp.dev\ndiffed them against each other.","measures":{"fuzzy_match_percent":23.202549,"total_code":3521820,"matched_code":711620,"matched_code_percent":20.20603,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2550,"matched_functions_percent":60.844666,"complete_code":711620,"complete_code_percent":20.20603,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":148}},{"timestamp":"2026-10-03T14:26:13Z","commit_sha":"28c5d0be4297f4357f03893403387afd56126485","commit_message":"decomp: improve resident rendering and UI matching (#78)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":23.202726,"total_code":3521820,"matched_code":711620,"matched_code_percent":20.20603,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2550,"matched_functions_percent":60.844666,"complete_code":711620,"complete_code_percent":20.20603,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":148}},{"timestamp":"2026-10-03T09:40:31Z","commit_sha":"c9b28e967f3b243deb61e7218f96567523b14848","commit_message":"overlay: 110 exact level overlay functions (C_EXACT 18.57 % → 20.15 %) (#77)\n\n* overlay: migrate 6 level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions\n\n* overlay: decompile and migrate more level overlay functions","measures":{"fuzzy_match_percent":23.201061,"total_code":3521820,"matched_code":709792,"matched_code_percent":20.154125,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2547,"matched_functions_percent":60.773087,"complete_code":709792,"complete_code_percent":20.154125,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":147}},{"timestamp":"2026-10-03T08:37:40Z","commit_sha":"1eaab66219717df08d054f4cd064ff658ce00e0d","commit_message":"assets: new logo (#76)\n\n* assets: replace logo with new version\n\n* assets: use transparent version of new logo","measures":{"fuzzy_match_percent":21.617449,"total_code":3521820,"matched_code":654020,"matched_code_percent":18.570513,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2437,"matched_functions_percent":58.148415,"complete_code":654020,"complete_code_percent":18.570513,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":144}},{"timestamp":"2026-10-03T08:09:59Z","commit_sha":"b91805eda738d3ec17e1c7a81d7419183eedd73b","commit_message":"decomp: recover GetStateTableWord return value (#75)\n\nCo-authored-by: Mateusz Kłysz <mateuszklysz@icloud.com>","measures":{"fuzzy_match_percent":21.617449,"total_code":3521820,"matched_code":654020,"matched_code_percent":18.570513,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2437,"matched_functions_percent":58.148415,"complete_code":654020,"complete_code_percent":18.570513,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":144}},{"timestamp":"2026-10-03T06:48:22Z","commit_sha":"8596f65870621fcee28af05ccafc1fd131f1fb29","commit_message":"config: classify float min/max helpers as intentional asm (#74)\n\nCo-authored-by: Mateusz Kłysz <mateuszklysz@icloud.com>","measures":{"fuzzy_match_percent":21.617449,"total_code":3521820,"matched_code":653984,"matched_code_percent":18.56949,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2436,"matched_functions_percent":58.124554,"complete_code":653984,"complete_code_percent":18.56949,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":143}},{"timestamp":"2026-10-03T06:43:57Z","commit_sha":"f4002d147cd5233442071c315597f0cecf6611bb","commit_message":"decomp: promote FUN_002075e8 (12 B) (#73)\n\nCo-authored-by: Mateusz Kłysz <mateuszklysz@icloud.com>","measures":{"fuzzy_match_percent":21.61735,"total_code":3521836,"matched_code":653984,"matched_code_percent":18.569405,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2436,"matched_functions_percent":58.09683,"complete_code":653984,"complete_code_percent":18.569405,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":143}},{"timestamp":"2026-10-03T05:58:41Z","commit_sha":"ba2f702ad27a5571449ede5fa52c288e02cdb554","commit_message":"fix: preserve precision for near-exact function scores (#72)\n\nCo-authored-by: Mateusz Kłysz <mateuszklysz@icloud.com>","measures":{"fuzzy_match_percent":21.617008,"total_code":3521836,"matched_code":653972,"matched_code_percent":18.569065,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2435,"matched_functions_percent":58.07298,"complete_code":653972,"complete_code_percent":18.569065,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":143}},{"timestamp":"2026-10-03T05:55:15Z","commit_sha":"b2e13cc61dc68d8435c137fa430551dd5c63f7f2","commit_message":"overlay: 82 exact level overlay functions (C_EXACT 17.20 % → 18.57 %) (#69)\n\n* overlay: decompile 7 more Veldin shared functions\n\n* overlay: decompile 2 more Veldin shared functions\n\n* overlay: decompile 4 more Veldin shared functions\n\n* overlay: decompile 2 more Veldin shared functions\n\n* overlay: decompile 2 more Veldin shared functions\n\n* overlay: decompile 1 more Veldin shared function\n\n* overlay: decompile 1 more Veldin shared function\n\n* overlay: migrate 63 level overlay functions","measures":{"fuzzy_match_percent":21.617008,"total_code":3521836,"matched_code":653972,"matched_code_percent":18.569065,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2435,"matched_functions_percent":58.07298,"complete_code":653972,"complete_code_percent":18.569065,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":143}},{"timestamp":"2026-10-03T05:30:03Z","commit_sha":"e3ad477d7ae81a17f03b8177975b099773a2f963","commit_message":"decomp: name the remaining memory-card states and group ui/menus (#71)\n\nName the eight memory-card state handlers left as FUN_ from the\ngame's own state-name table (0x001A03D0, parallel to the handler table\nat 0x001A0438), and move them with run_state_handler into\nui/menus/save_data. Name font_print_wrapped and its small-font\nwrapper and move both to ui/text. Group the item-preview helpers in\nui/menus/item_preview and the pause helpers in ui/menus/pause.\n\nThe boot ELF still rebuilds byte-for-byte.","measures":{"fuzzy_match_percent":20.274414,"total_code":3521836,"matched_code":606688,"matched_code_percent":17.226469,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2354,"matched_functions_percent":56.14119,"complete_code":606688,"complete_code_percent":17.226469,"complete_data":0,"complete_data_percent":0,"total_units":439,"complete_units":139}},{"timestamp":"2026-10-03T05:16:35Z","commit_sha":"d2e38ec2282d6b77bbe1f617c7a2f64cf2686066","commit_message":"decomp: improve resident menu resources and rendering (#70)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":20.274414,"total_code":3521836,"matched_code":606688,"matched_code_percent":17.226469,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2354,"matched_functions_percent":56.14119,"complete_code":606688,"complete_code_percent":17.226469,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":137}},{"timestamp":"2026-10-02T23:44:38Z","commit_sha":"f10ca43d95edef7596bbc1b745a28aa5129703fe","commit_message":"decomp: apply evidence-backed names and fix the names catalog paths (#65)\n\n* decomp: apply evidence-backed names and fix the names catalog paths\n\nRename 27 functions from their recovered-name proposals (C name bound to\nthe unchanged FUN_ symbol with __asm__), including the 17 memory-card\nstate handlers save_card_state_*, which move to ui/menus/save_data.\nFold ui/font into ui/fonts and ui/memory/hud_heap_reset into ui/hud.\n\nSync config/us/recovered_names.json with the source tree: 181 proposal\nand 233 symbol records pointed at units that had moved, so the rename\ntool skipped them as conflicts.\n\nThe boot ELF still rebuilds byte-for-byte; C_EXACT is unchanged at\n17.19 %.\n\n* chore: leave the progress report to CI\n\n* chore: keep the regenerated progress report until CI publishes it","measures":{"fuzzy_match_percent":20.209892,"total_code":3521836,"matched_code":605904,"matched_code_percent":17.204208,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2353,"matched_functions_percent":56.117336,"complete_code":605904,"complete_code_percent":17.204208,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":137}},{"timestamp":"2026-10-02T23:35:26Z","commit_sha":"8e4321cefa8451ca2710ac08ea771988c2c541f7","commit_message":"chore: read C_FUZZY from Lombyte-Tools instead of building in CI (#67)\n\nThe progress job no longer runs setup.sh and make elf on main: it copies the\nfuzzy scores the decomp workbench keeps in the private tooling repository\n(the one file, through LOMBYTE_TOOLS_TOKEN) and falls back to the scores last\npublished on the progress branch when the secret is not available.","measures":{"fuzzy_match_percent":20.209892,"total_code":3521836,"matched_code":605904,"matched_code_percent":17.204208,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2353,"matched_functions_percent":56.117336,"complete_code":605904,"complete_code_percent":17.204208,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":138}},{"timestamp":"2026-10-02T23:20:33Z","commit_sha":"be2d870ee22cb19d14a44cce88ad1ffa6518ca40","commit_message":"decomp: improve resident C matching and names (#66)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":20.261215,"total_code":3521836,"matched_code":605904,"matched_code_percent":17.204208,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2353,"matched_functions_percent":56.117336,"complete_code":605904,"complete_code_percent":17.204208,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":138}},{"timestamp":"2026-10-02T21:44:33Z","commit_sha":"3b6adfc2ac6ea0126413873409579d472d8788d7","commit_message":"overlay: 35 exact Veldin shared functions (C_EXACT 16.45 % → 17.19 %) (#63)\n\n* overlay: 10 exact Veldin shared functions (12,136 B)\n\n* chore: regenerate the progress report and map\n\n* overlay: decompile 15 more Veldin shared functions\n\n* chore: regenerate the progress report and map\n\n* overlay: decompile 5 more Veldin shared functions\n\n* chore: regenerate the progress report and map\n\n* overlay: decompile 5 more Veldin shared functions\n\n* chore: regenerate the progress report and map","measures":{"fuzzy_match_percent":20.238722,"total_code":3521836,"matched_code":605396,"matched_code_percent":17.189783,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2352,"matched_functions_percent":56.09349,"complete_code":605396,"complete_code_percent":17.189783,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":138}},{"timestamp":"2026-10-02T18:07:32Z","commit_sha":"d801b23bcd3d1677e867e46e47332e8df1ebce82","commit_message":"fix: split the tail-call entry at 0x12cc20 out of its text gap (#60)\n\n0x12cc20 opens with its own frame (addiu sp, sp, -0x20) and is reached by\na j from the set_d3_chcr unit at 0x12cb34, so it is a separate function.\nIt gets its own textbin subsegment after the 4-byte pad. The rebuilt boot\nELF still matches retail.","measures":{"fuzzy_match_percent":19.497631,"total_code":3521836,"matched_code":579296,"matched_code_percent":16.448692,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2317,"matched_functions_percent":55.258766,"complete_code":579296,"complete_code_percent":16.448692,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":134}},{"timestamp":"2026-10-02T17:58:29Z","commit_sha":"fab96661d7621ac2d0f102753765cf6c34eccaa2","commit_message":"overlay: Veldin shared wave and an assembler without div padding (C_EXACT 15.99 % → 16.45 %) (#62)\n\n* fix: install Ps2EeAs without its divbug padding\n\nRetail has no NOP padding in front of any div (0 of 346 in the executable,\n0 of 26,539 in the level overlays), so the assembler retail used did not\napply the workaround. setup.sh now patches 6 bytes of ps2eeas 1.9.25.758 to\nskip the branch and label checks; the full-ELF gate still passes and every\npromoted overlay function stays exact.\n\n* overlay: 10 functions that were exact but for the div padding\n\n* decomp: two executable units, a matrix-to-quaternion helper and a pause-menu gap function\n\n* overlay: 3 migrated functions\n\n* overlay: 27 exact functions from the Veldin shared wave\n\n* chore: regenerate the progress report and map","measures":{"fuzzy_match_percent":19.497631,"total_code":3521836,"matched_code":579296,"matched_code_percent":16.448692,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4193,"matched_functions":2317,"matched_functions_percent":55.258766,"complete_code":579296,"complete_code_percent":16.448692,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":134}},{"timestamp":"2026-10-02T17:47:52Z","commit_sha":"f9d06e19eca83f72e6c9331e75f3e23cc83b44b4","commit_message":"docs: add Moby selector scratch-path note (#61)\n\n* Add documentation for Moby selector-to-scratch path\n\nThis document provides a detailed reference for the Moby selector-to-scratch transform path used in the USA / NTSC-U boot executable `SCUS_971.99`. It outlines the relationships between assembly units and their corresponding operations, along with terminology and evidence limits.\n\n* docs: simplify Moby selector scratch-path note","measures":{"fuzzy_match_percent":19.037926,"total_code":3521784,"matched_code":562976,"matched_code_percent":15.985535,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4192,"matched_functions":2279,"matched_functions_percent":54.36546,"complete_code":562976,"complete_code_percent":15.985535,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":132}},{"timestamp":"2026-10-02T17:11:44Z","commit_sha":"24a2321bb091399ca0b1857791f2c20e10f852e8","commit_message":"docs: add the memory-card state evidence to the 19 level programs (475 places) (#58)\n\nEach level program carries the memory-card state machine: a dispatcher indexes a\nhandler table with the current state and calls the entry, and the table of state\nnames follows the handler table (same length, last slot null) with the game's own\nnames CS_INIT through CS_PROMPT_BEGIN_NOSAVE. The state index names the handler.\n\n475 places across the 19 programs (25 per level, one per state) get a\nname_evidence row with method \"memory-card-state-record\" and source\n\"memory-card-state\". The name is the one #33 already merged for the 17 states the\nboot side covered (save_card_state_init, save_card_state_no_card); the 8 it did\nnot cover follow the same style (save_card_state_wait_for_card,\nsave_card_state_no_save). Each row keeps the state as the game writes it.\n\nMeasured against upstream/main at 0271b7e: 475 of 475 places resolve to 21\ncatalogue rows, 0 outside the catalogue, 0 level-count disagreements, and 0\naddresses were already present in the names files.\n\nThe naive derivation is wrong in both directions and was measured before\nsending: CS_NOCARD would give \"nocard\" where #33 merged \"no_card\", and\nCS_NOSAVE \"nosave\" where the family style is \"no_save\". The 17 merged names are\nread from the catalog's own evidence (\"Handler of state CS_x\"), not re-derived.\n\nVerification: the 19 files parse, are LF only, stay sorted by address and hold no\nduplicate address; scripts/generate_treemap.py load_overlay_names() still yields\nthe same 247 boot-address pairs. No src/ file and no game bytes.\n\nRefs #31.\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":19.037926,"total_code":3521784,"matched_code":562976,"matched_code_percent":15.985535,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4192,"matched_functions":2279,"matched_functions_percent":54.36546,"complete_code":562976,"complete_code_percent":15.985535,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":132}},{"timestamp":"2026-10-02T17:08:01Z","commit_sha":"8cf7999a07a38b67836d200c96953765f0cfcf72","commit_message":"fix: split the jal entry at 0x1f7cd0 out of its text gap (#59)\n\nThe textbin gap at 0x1f7c10 held two functions; 0x1f7cd0 is called by\njal at 0x1f86f8, so it gets its own textbin subsegment. The rebuilt boot\nELF still matches retail.","measures":{"fuzzy_match_percent":19.037926,"total_code":3521784,"matched_code":562976,"matched_code_percent":15.985535,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4192,"matched_functions":2279,"matched_functions_percent":54.36546,"complete_code":562976,"complete_code_percent":15.985535,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":132}},{"timestamp":"2026-10-02T16:28:09Z","commit_sha":"dfd223afb03590fc3f9a8b6fb304db05a729f15d","commit_message":"overlay: 122 exact functions from the Veldin waves and the level-18 sweep (53364 B) (#54)\n\n* overlay: migrate three level-code functions (296 B)\n\nFUN_L03_002c6c60 (44 B), FUN_L03_002c6c90 (12 B) and FUN_L14_003087c0 (240 B) come from the cross-project exchange, paired by position with the US constants and proven exact on the level catalogue. The ported bodies name their foreign source.\n\n* overlay: decompile 31 shared Veldin-1 functions (3556 B)\n\nA wave of 14 workers on the level-00 shared queue (415 rows <= 2.8 KB, split by bytes). All 31 are exact on the overlay proof: the game route, the candidate placed at its canonical level address with every relocation resolved. Levers that made the last rows: a goto on one shared return label against cross-jumping; switch vs if/else two-return tails; qzero() for the direct sq $0; extern T X[] vs extern T *; a float threshold through a float local; an 83-case jump table rebuilt from the jr table. Near misses and walls are banked in the tooling repository.\n\n* fix: count one-line overlay C definitions in the progress report\n\noverlay_units' definition pattern required the parameter list to close the line, so a promoted tiny function written as 'int F(void) { ... }' stayed pending: FUN_L00_00211360 of this batch and 86 older units (7,380 B) were undercounted. The pattern now accepts a body opening on the same line and still rejects a prototype. Regression test added.\n\n* chore: regenerate progress report\n\n513,336 / 3,521,568 B = 14.58 % (was 502,136 = 14.26 %); 2,186 / 4,191 functions = 52.16 % (was 2,083 = 49.70 %). This batch's 34 promotions are 3,852 B; the one-line definition fix recovered 86 functions (7,380 B) that the report had counted pending.\n\n* decomp: fun_00225588 ported from the cross-project exchange\n\nThe unit's C from the sister decompilation proves byte-exact on the game compiler; it is a new unit in the link order (216 B, ui/menus).\n\n* overlay: 44 level-code functions from exact relatives and the exchange (28472 B)\n\n44 shared/level functions, all exact on the overlay proof (game compiler, placed at their canonical addresses, every relocation resolved). 10 come from the sister decompilation's cross-project exchange; the other 34 were ported from exact relatives already in this tree (per-level arm sets, level-data remaps, one to three statements each). The wave's near misses and walls stay banked in the tooling repository.\n\n* chore: regenerate progress report\n\n542,024 / 3,521,784 B = 15.39 % exact bytes (was 513,336 = 14.58 %); 2,231 / 4,192 functions = 53.22 %. This batch: 45 exact functions (44 overlay + 1 executable, 28,688 B).\n\n* overlay: 41 PAL-imported functions from the level-18 sweep and the placeholder alignment (20360 B)\n\n* decomp: stage 99 near-miss bodies into the assembly tree\n\n* chore: regenerate progress report\n\n* overlay: promote two shared Veldin-1 functions (464 B)\n\n* decomp: stage the remaining near-miss bodies\n\n* chore: regenerate progress report","measures":{"fuzzy_match_percent":19.037926,"total_code":3521784,"matched_code":562976,"matched_code_percent":15.985535,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4192,"matched_functions":2279,"matched_functions_percent":54.36546,"complete_code":562976,"complete_code_percent":15.985535,"complete_data":0,"complete_data_percent":0,"total_units":438,"complete_units":132}},{"timestamp":"2026-10-02T15:37:21Z","commit_sha":"7abd1fd929b48ec2c5cd53315f8f61a4693b7866","commit_message":"docs: add moby class naming evidence to the 19 level programs (1,373 functions) (#57)\n\nEvery level program carries a lvl.vtbl dispatch table of 12-byte records\n{class id, handler, shared pointer}. Wrench's unpack writes one directory per\nclass whose name carries that id (moby_classes/gameplay/726_novalis_elevator),\nso the record's first word names its handler. 2,997 records across the 19\nprograms; 2,015 carry an id the unpack names (671 named ids) -- 1,373 distinct\nfunctions over 385 catalogue rows, 387 distinct class names.\n\nThis adds that evidence to config/overlays/us/names/level-NN.json as\nname_evidence rows with method \"moby-class-record\" and source \"moby-class\":\n1,344 new entries, plus 29 existing preview-only entries that now carry a name\n(their preview field is kept, \"moby-class\" is appended to sources). 150 of the\n1,373 functions serve more than one class (bolt/bolt_hexnut, the eleven *_ammo\npickups, the nine gold weapons); the full lists stay in class_ids and\nclass_names, so nothing is flattened. The primary name is the lowest class id.\n\nMeasured against upstream/main at 0271b7e, after the split-rule fix: 0 of the\n1,373 rows fall outside the catalogue. 29 entries still carried a pre-#47 row\nname that no longer exists in the catalogue (FUN_002e1720 became\nFUN_L00_002d37d0, FUN_0030bf98 became FUN_L05_0030bf98); their function field\nis refreshed to the current catalogue name.\n\nVerification: the 19 files parse, are LF only, stay sorted by address and hold\nno duplicate address; scripts/generate_treemap.py load_overlay_names() still\nyields the same 247 boot-address pairs, so the treemap and the progress report\nare unchanged. No src/ file and no game bytes.\n\nRefs #31.\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":16.360928,"total_code":3521568,"matched_code":505496,"matched_code_percent":14.354288,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2089,"matched_functions_percent":49.844906,"complete_code":505496,"complete_code_percent":14.354288,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":125}},{"timestamp":"2026-10-02T12:53:12Z","commit_sha":"0271b7e3dd2f8076315f21ac0c67532ed8b48dab","commit_message":"decomp: recover MPEG picture helpers and promote two exact units (#52)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":16.360928,"total_code":3521568,"matched_code":505496,"matched_code_percent":14.354288,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2089,"matched_functions_percent":49.844906,"complete_code":505496,"complete_code_percent":14.354288,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":125}},{"timestamp":"2026-10-02T11:21:34Z","commit_sha":"3e7cb43025dd0dbdbfc6cb02dee2e85c57850000","commit_message":"decomp: promote SDK file I/O functions (2524 B) (#51)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":16.359625,"total_code":3521568,"matched_code":504660,"matched_code_percent":14.330548,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2087,"matched_functions_percent":49.797184,"complete_code":504660,"complete_code_percent":14.330548,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":125}},{"timestamp":"2026-10-02T11:12:08Z","commit_sha":"4cf9e6045a38e812f9a35740db13df189b7e372e","commit_message":"decomp: improve dialogue and configured text rendering (#53)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":16.355484,"total_code":3521568,"matched_code":502136,"matched_code_percent":14.258876,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2083,"matched_functions_percent":49.70174,"complete_code":502136,"complete_code_percent":14.258876,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":125}},{"timestamp":"2026-10-02T09:19:40Z","commit_sha":"f1a04ab4631c119b4da798a2450925e62a857d66","commit_message":"docs: update recovered engine source layout reference with STABS symbols and build findings (#55)\n\nExpand docs/engine-source-layout.md with newly recovered engine metadata:\n- IOP Stash Subsystem (IOPSTASH.IRX): full STABS / .mdebug types and RPC\n  interface (IOP_STASH_SEND, IOP_STASH_FETCH, IOP_STASH_INFO) along with\n  authentic StashInfo, StashBlock, StashFetch, and StashGetInfo struct\n  definitions, resolving placeholder types in src/storage/cd/fun_00232d00.c,\n  src/world/data/stash_send_data.c, and src/storage/stash/stash_receive_data.c.\n- Sound Driver Subsystem: /usr/local/989snd/ee/989snd.c source path and\n  exported sound bank loading prototypes.\n- Developer attributions and assertions: RAR (Rich A. Rayl) collision\n  testing, TJB (Ted J. Baker) environment lighting, MB_CheckCollPill,\n  and IMoby validation.\n- Prerelease milestone notes: September 9, 2002 review build hardware\n  WibuKey USB dongle protection, cheat sequence, and Level 18 timeline.","measures":{"fuzzy_match_percent":16.334517,"total_code":3521568,"matched_code":502136,"matched_code_percent":14.258876,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2083,"matched_functions_percent":49.70174,"complete_code":502136,"complete_code_percent":14.258876,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":125}},{"timestamp":"2026-10-02T04:52:37Z","commit_sha":"67ecb29571fd446345084c6322aa45f836402fcf","commit_message":"decomp: derive FUN_001fa2b8 matrix copy (#38)\n\nCo-authored-by: Ben Perry <7693062+ben-perry@users.noreply.github.com>","measures":{"fuzzy_match_percent":16.334517,"total_code":3521568,"matched_code":502136,"matched_code_percent":14.258876,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2083,"matched_functions_percent":49.70174,"complete_code":502136,"complete_code_percent":14.258876,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":125}},{"timestamp":"2026-10-01T16:33:11Z","commit_sha":"eefa15b35333081026384cb49706ec9d4335e25a","commit_message":"decomp: the eight memory-card state handlers in text gaps (issue #9) (#49)\n\nThe boot's memory-card state machine has 25 handlers; 17 were units, 8\nsat inside text gaps (CS_WAIT_FOR_CARD 0x2089D0, CS_UNFORMATTED 0x208A38,\nCS_PROMPT_FORMAT 0x208A78, CS_CHECKING_SAVE 0x208C00, CS_NOSAVE 0x208C70,\nCS_CREATE_SAVE_PENDING 0x208D20, CS_NEWCARD 0x208DD8,\nCS_PROMPT_BEGIN_UNFORMATTED 0x208FA0). Each is cut at its table entry and\nends at its own return before the padding; all eight are exact C in\nui/menus next to their siblings.","measures":{"fuzzy_match_percent":16.318533,"total_code":3521568,"matched_code":502136,"matched_code_percent":14.258876,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4191,"matched_functions":2083,"matched_functions_percent":49.70174,"complete_code":502136,"complete_code_percent":14.258876,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":125}},{"timestamp":"2026-10-01T16:32:32Z","commit_sha":"fff29869b9839dbb693d0aa12a4ce62fd7a41d08","commit_message":"fix: read and write the report and map as UTF-8 (#50)\n\n#48 regenerated assets/decomp_map.svg on a machine whose default encoding\nis not UTF-8: the middle dots in the tooltips came out as single 0xB7\nbytes, the file stopped being well-formed XML and GitHub showed no map.\nEvery read_text/write_text in generate_treemap.py and\ngen_progress_report.py now names its encoding.","measures":{"fuzzy_match_percent":16.301325,"total_code":3520844,"matched_code":501412,"matched_code_percent":14.241244,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4183,"matched_functions":2075,"matched_functions_percent":49.605545,"complete_code":501412,"complete_code_percent":14.241244,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":125}},{"timestamp":"2026-10-01T16:23:40Z","commit_sha":"02d0faa4e33f0c969c0fab361cbf801d7db344b2","commit_message":"fix: overlay function rows start only at real entry points (#31) (#47)\n\n* overlay: a function row is an entry point of the retail code (issue #31)\n\nconfig/overlays/us/functions.tsv regenerated: 4031 -> 3908 rows, level 00\n2305 -> 1965 starts. The old rule cut a row at every `jr $ra` and every frame\nopener, which made a shared epilogue, a loop body or the tail of a function a\n\"function\" of its own - 342 such places in level 00 alone - and a fragment\ncannot be written in C because it never was a function in the original.\n\n- 390 rows the old rule cut out of a longer function are gone; the bytes stay in\n  the neighbouring row, which now ends at its last reachable instruction\n- the stub files are regenerated from the new boundaries (3169 functions), and\n  all 3169 stubs are EXACT\n- 1026 promoted functions keep their exact bytes\n- 6 overlay copies of functions the executable already holds in C are removed\n  (the catalogue names those rows after the executable's function now)\n- 37 promoted functions still name a row that has no place in their level (a\n  call to an address the new catalogue does not treat as a start); they need\n  hand work and `decomp overlays check` lists them\n- config/overlays/us/confirmed-starts.tsv: 17 function starts no rule finds\n  (nothing in the level calls them, no table names them); each carries promoted\n  C that compiles to exactly its bytes as the evidence\n- docs/overlays.md: the rule, and the measured dispatch-record, $gp and\n  catalogue numbers\n\n* overlay: fix the entry-point split so every copy and caller stays matched (issue #31)\n\nThe first version of the rule lost functions and broke promoted C:\n- the fingerprint covered the whole segment, so copies of one function\n  landed in different rows (C references to them stopped linking);\n- uncalled functions that load an argument before the prologue, and\n  tail-call targets, were no longer starts;\n- switch cases (jr through a jump table), branch delay slots and j inside\n  a body were cut off the reachable size;\n- executable copies took their size from reachability instead of the\n  executable function;\n- renamed callees kept their old name at some call sites, and calls that\n  retail sends to 0x25C338 were pointed at FUN_L00_002603d0.\n\nNow: 3758 rows (772 exe, 1645 shared, 1341 level), level 00 has 1981\nstarts (was 2305 before the rule), 2986/2986 stubs exact, and every\npromoted overlay function that checked exact before still does\n(1010 of 1026). Three hand-confirmed starts are found by the rule and\ndropped from confirmed-starts.tsv; a confirmed start now cuts every copy.\n\n* overlay: keep stubs where main had them; no function in two files\n\nThe boundary change moved 1,611 stubs out of the files that hold C into\nnew stub-only files, and regenerating after the fix left stubs of the old\nlayout in place: 886 functions were in the tree two or three times and\n98 files held only their #include lines. Stubs are back at their place in\nthe C files, new rows get their own stub files (5 new, 7 renamed against\nmain), and every catalogue row is in the tree exactly once.\n\nFive overlay C bodies that the new rows show to be copies of executable\nfunctions with C already (FUN_002141f8, FUN_0021a1b0, FUN_0021a318,\nFUN_0021cb00, FUN_00208980) are dropped, like the six before them.\n\n* overlay: confirmed-starts header points at docs/overlays.md\n\n* overlay: keep the uncalled leaf functions the split dropped\n\nGetters and return-0 bodies that nothing in a level calls, with no frame\nand under 32 bytes (`lui; lbu; jr $ra; sltu`, `jr $ra; daddu $v0, $zero,\n$zero`), had fallen out of the catalogue: 864 places, 11,620 B, every one\na row before. A whole leaf right after a return (its own `jr $ra`, no $sp\naccess, no trap) is a start again. No existing row changes; five rows and\n864 places come back. Unowned bytes are now only dead tails with no\nreturn.\n\n3763 rows (773 exe, 1648 shared, 1342 level), 2990/2990 stubs exact,\n1015 of 1031 promoted overlay functions exact (the same 16 fail on main).\n\n* overlay: fix two functions from #48 (one file did not compile, one level-data name)\n\nFUN_L01_0026e0e0 declared D_L01_001ABCC0 a second time with another type,\nso math_interpolation_0026d930.c stopped compiling and took\nFUN_L01_0026e090 with it; the file's own declaration is enough.\nFUN_L18_002fa888 read level 18's moby table through D_L00_0015FFD8; a\nlevel's own data above 0x15EF00 is named after that level, D_L18_0015FFD8.\nBoth functions are exact.\n\n* docs(overlays): drop counts that go stale with every catalogue change","measures":{"fuzzy_match_percent":16.301325,"total_code":3520844,"matched_code":501412,"matched_code_percent":14.241244,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4183,"matched_functions":2075,"matched_functions_percent":49.605545,"complete_code":501412,"complete_code_percent":14.241244,"complete_data":0,"complete_data_percent":0,"total_units":437,"complete_units":125}},{"timestamp":"2026-10-01T15:21:15Z","commit_sha":"b030ebf2b23b71b125e0641506e9e021a9bf8b37","commit_message":"overlay: promote three level-code functions ported from rac1-decomp (260 B) (#48)\n\n* overlay: promote two level-code functions ported from rac1-decomp (176 B)\n\nFUN_L01_0026e0e0 and FUN_L18_002fa888 (88 B each), both exact in the PAL\ndecompilation and re-checked byte for byte here on the game compiler route\n(cc1 sce-991111b + ps2eeas, the assembler the build uses).\n\nFUN_L01_0026e0e0 is the neighbour variant of FUN_L01_0026e090 already in the\ntree: same shape, but the datum needs the unsplit macro form, so it is\ndeclared through a .sdata alias beside the file's own declaration.\n\nprogress/report.json and assets/decomp_map.svg + .json regenerated in the\nsame commit.\n\n* overlay: promote FUN_L14_00307a80, ported from rac1-decomp (84 B)\n\nThe size-matched PAL neighbour for this address was the callback the function\nenqueues, not the body: the real one is func_L14_00308F08, the two-state moby\nswitch next to it in the same file. Re-checked byte for byte on the game\ncompiler route (cc1 + ps2eeas): exact, 84 B.\n\nprogress/report.json and assets/decomp_map.svg + .json regenerated.\n\n---------\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":16.153673,"total_code":3558980,"matched_code":501624,"matched_code_percent":14.0946,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":2081,"matched_functions_percent":45.907787,"complete_code":501624,"complete_code_percent":14.0946,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":115}},{"timestamp":"2026-10-01T12:38:14Z","commit_sha":"3f622bfca80a4fe2663e4e1dc751d22c979aeb59","commit_message":"fix: apply the gas 0020 size-at-use rule in noreorder mode (#46)\n\nDrops `! mips_opts.noreorder &&` from the condition P20 adds: a reference to a\nsymbol whose size is not yet known at the use now takes the absolute\n`lui %hi` + `op %lo` pair in reorder and noreorder alike, which is what\nPs2EeAs emits there. On the 13 constructed cases of #9 (instructions only,\nrelocations excluded) that is 13/13 against 8/13 before, with no case lost.\n\nRemoves the second hunk (the `md_convert_frag` rewrite): the four fixtures in\nthe entry assemble byte-identical with and without it, and four more forms\nbuilt on purpose to reach it stayed inert.\n\nREADME entry updated for 0020: new patch SHA-256, and the role now states the\nnoreorder case follows the same size-at-use rule.\n\nNot measured here: `make elf` and the 58-control parity (no game data or\nbaseline in this checkout).\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":16.146368,"total_code":3558980,"matched_code":501364,"matched_code_percent":14.087295,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":2078,"matched_functions_percent":45.841606,"complete_code":501364,"complete_code_percent":14.087295,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":115}},{"timestamp":"2026-10-01T07:36:30Z","commit_sha":"c26079442360538f261d688d14f298bf677ae7bc","commit_message":"overlay: decompile 26 more shared veldin functions (16,068 B) (#45)\n\n* overlay: decompile 3 more shared veldin functions (wave 7, part 1)\n\n* overlay: decompile 18 more shared veldin functions (11780 B)\n\nShared functions canonical in Veldin (level 00), present in up to 19\nlevels; migrated functions finished by hand where the automatic transfer\nfell short. Each proved byte for byte against its level text; make\noverlays and the full-ELF gate pass on the tree merged with main.\n\n* overlay: decompile 5 more shared veldin functions (2964 B)\n\nShared functions canonical in Veldin (level 00), each proved byte for\nbyte against its level text; make overlays and the full-ELF gate pass.\n\n* chore: regenerate progress report","measures":{"fuzzy_match_percent":16.146368,"total_code":3558980,"matched_code":501364,"matched_code_percent":14.087295,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":2078,"matched_functions_percent":45.841606,"complete_code":501364,"complete_code_percent":14.087295,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":115}},{"timestamp":"2026-10-01T06:57:29Z","commit_sha":"1373b533ca5839efa56b1897d764e2d3bca17cd8","commit_message":"overlay: migrate 319 level functions (74,644 B) (#44)\n\n* overlay: migrate 30 more level functions (5,128 B)\n\n30 shared and level functions (canonical in 12 levels, present in all 19),\neach proved byte for byte against its level text (overlay-place-bytes-v1);\nmake overlays and the full-ELF gate pass.\n\n* overlay: migrate 7 more level functions (1,900 B)\n\nSeven shared and level functions (canonical in levels 01, 02, 03 and 08),\neach proved byte for byte against its level text; make overlays and the\nfull-ELF gate pass.\n\n* overlay: migrate 12 more level functions (3,448 B)\n\nTwelve shared and level functions (canonical in levels 00, 02, 04, 06, 08,\n10, 11, 16 and 17), each proved byte for byte against its level text; make\noverlays and the full-ELF gate pass.\n\n* overlay: migrate 10 more level functions (3,800 B)\n\nTen shared and level functions (canonical in levels 01, 02, 03, 06, 08,\n13, 16 and 18), each proved byte for byte against its level text; make\noverlays and the full-ELF gate pass on the tree merged with main.\n\n* overlay: migrate 7 more level functions (2,412 B)\n\nSeven shared and level functions (canonical in levels 00, 02, 06, 17 and\n18), each proved byte for byte against its level text; make overlays and\nthe full-ELF gate pass.\n\n* chore: regenerate progress report\n\nAfter the 66 level functions of this branch: matching code 408,568 ->\n425,256 B (11.48 % -> 11.95 %). Report --check passes.\n\n* overlay: migrate 257 more level functions (58,268 B)\n\n257 shared and level functions, canonical in all 19 levels, each proved\nbyte for byte against its level text. Three functions of this branch that\nthe merge with main had to drop (FUN_L06_002f96f8, FUN_L06_002fb2a8,\nFUN_L06_002fb668) are back in their unit file. make overlays and the\nfull-ELF gate pass.\n\n* chore: regenerate progress report\n\nMatching code after this branch on the current main.\n\n* chore: regenerate progress report\n\nOn the tree merged with main.","measures":{"fuzzy_match_percent":15.69489,"total_code":3558980,"matched_code":485296,"matched_code_percent":13.635817,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":2052,"matched_functions_percent":45.268036,"complete_code":485296,"complete_code_percent":13.635817,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":115}},{"timestamp":"2026-10-01T06:50:44Z","commit_sha":"047f7e39908f0b30bc522f8d359ae6751c2af959","commit_message":"overlay: promote FUN_L00_00233288, ported from rac1-decomp (68 B) (#43)\n\nPorted from rac1-decomp (PAL), exact there; reference re-anchored on this build by position, body re-checked byte for byte on the game compiler route. Four more functions from the same sweep (FUN_L00_0020a1e0, FUN_L00_0028df38, FUN_L00_002118b0, FUN_L00_00232628) are already promoted upstream in the meantime, so this PR carries only the one that is not. progress/report.json and assets/decomp_map.* regenerated in the same commit.\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":13.5835,"total_code":3558980,"matched_code":410652,"matched_code_percent":11.538475,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1733,"matched_functions_percent":38.23075,"complete_code":410652,"complete_code_percent":11.538475,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-10-01T06:23:01Z","commit_sha":"357774f714352a1c03b135b5d360072e6dd853be","commit_message":"overlay: promote nineteen level-code functions ported from rac1-decomp (2016 B) (#42)\n\nPorts from rac1-decomp (PAL), exact there: every reference re-anchored on this build by position, each body re-checked byte for byte on the game compiler route. The data declarations use the MACRO_ADDR spelling (include/sda.h) -- measured: on the level-06 series that is what reproduces retail's address materialisation. progress/report.json and assets/decomp_map.* regenerated in the same commit.\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":13.58159,"total_code":3558980,"matched_code":410584,"matched_code_percent":11.536564,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1732,"matched_functions_percent":38.20869,"complete_code":410584,"complete_code_percent":11.536564,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-10-01T06:10:17Z","commit_sha":"7a440972bf8c7c552d2ddddba63b83a8c55a35c9","commit_message":"fix: repository audit, plus seven Oltanis promotions with the small-data fix (#41)\n\n* fix: repo hygiene found by the audit (hook check, stale names, asm escapes)\n\n- scripts/build-game-compiler.py has a shebang but was not executable, so\n  pre-commit's check-shebang-scripts-are-executable failed on a clean tree.\n- list-functions.py and normalize-pending-bodies.py looked for the sibling\n  tooling checkout under its old name (RncDecomp-tools); rename-function-\n  proposals.py still called the game checkout RncDecomp.\n- The four COP0 units wrote the Status register as \"\\$12\": cc1 warned\n  \"unknown escape sequence\" on every build. Written as \"$12\"; the gate\n  PASSes with identical bytes.\n- sce_sif_init_iop_heap.c carried a STATE/SCORE header, which promoted\n  units must not have; replaced by a one-line note on its legacy flag.\n- Makefile header named the project by its old name.\n\nmake elf: PASS: reconstructed boot ELF matches retail\n\n* docs: fix the commit hook path and stale layout references\n\n- CONTRIBUTING.md told contributors to link ../scripts/commit-msg.py from\n  .git/hooks/, which resolves to .git/scripts/ and never runs; it is\n  ../../scripts/commit-msg.py.\n- src/README.md described a src/textbin/ tree that no longer exists;\n  it now points at src/overlays/ instead.\n- docs/building.md referenced docs/project-map.md, which exists in neither\n  repository.\n- docs/progress-metrics.md presented promote-unit.py as a public script;\n  it is maintainer tooling and is not in scripts/.\n- docs/progress-metrics.md: trailing blank line (end-of-file-fixer).\n\n* fix: build and setup script defects found by the audit\n\n- Makefile: `make iso` exited its subshell and then ran rebuild-iso.py with\n  an empty --iso; `make progress` and the `elf` receipt ignored BASELINE_ROOT\n  and looked for build/SCUS_971.99, which no step produces; `make overlays`\n  used whatever ninja was on PATH instead of the venv's; the header told\n  users to run bare `make` (= `check`).\n- setup.sh: `\"${args[@]}\"` on an empty array aborted `--docker` under bash\n  3.2 (macOS, the one platform that path exists for); `--iso`/`--elf` with\n  no value tripped `set -u` instead of a message; `--help` read `$0` after\n  `cd`, breaking a relative invocation and cutting the banner short; the\n  \"replacing it\" warning fired even when nothing was there to replace with.\n- rebuild-iso.py: usage and the error message named build/SCUS_971.99 and\n  extracted/SCUS_971.99; the gate leaves the ELF in the baseline workspace.\n- commit-msg.py: the docstring's install line was a dangling link with the\n  wrong file name and pointed at a script that does not exist; subjects git\n  writes itself (Merge, Revert, fixup!, squash!) are no longer rejected.\n- check-unit.py: the help examples were intentional-asm units the script\n  refuses; they are now scorable pending units.\n- materialize-textbin-oracles.py honours BINUTILS_ROOT like check-unit.py.\n- configure.py: the per-unit flag tables are exact-match on the owner path;\n  their comments claimed suffix matching.\n- verify-baseline.sh: unguarded $HOME under set -u.\n- progress.yml: the compilers are public downloads this repository may not\n  redistribute, not \"not public\".\n\nmake elf: PASS: reconstructed boot ELF matches retail\n\n* docs: make the contributor walkthrough runnable and correct stale facts\n\n- CONTRIBUTING.md: the worked example (subtract_integer_with_clamp) is an\n  intentional-asm unit that check-unit refuses, and the other example\n  (assembly/math/sign_extend_packed_value) is not an assembly/ owner; both\n  replaced by assembly/textbin/runtime/memory/clear_u64_value, which runs.\n  The symbol is the INCLUDE_ASM argument (no SYMBOL: header exists), aliases\n  are FUN_<address>, `make check` also runs the progress report check, the\n  progress job is a workflow, list-functions defaults are described, and\n  the pre-commit config is mentioned.\n- docs/commit-messages.md: the hook install path was a dangling symlink.\n- docs/building.md: a sentence said nothing is downloaded, contradicting\n  setup.sh; the targets table lacked `make iso` and `make overlays`; the\n  --no-build/--with-patched flags and the /opt binutils fallback are listed.\n- docs/patched-toolchain.md and patches/ee-gcc-2.9-991111-01/README.md: the\n  patch is 203 inserted / 15 deleted lines over 9 files; local-alloc.c was\n  missing from the table. setup.sh --with-patched is mentioned.\n- patches/README.md: the production stack ends at 0056, not 0055.\n- patches/sce-991111b/README.md: a private host path removed; 0035 is not a\n  published patch (its listed hash is the empty-file hash).\n- config/README.md: overlays live under src/overlays/, not an\n  overlay/us/level-NN/ namespace; the three unmentioned tracked files are\n  listed.\n- dumps/README.md pointed at a README section that does not exist;\n  tools/README.md called the SN tree \"retiring\" although Ps2EeAs assembles\n  all game code; decompilation-tips.md said pending owners live only under\n  assembly/textbin/; src/assembly/README.md described the oracle idiom\n  wrongly; src/README.md lists overlays.\n\n* overlay: promote four Oltanis functions ported from rac1-decomp (680 B)\n\nsrc/overlays/l14/unclassified_002460f8.c\n- FUN_L14_002b5c98 (124 B) -- clears the moby's link to its slot entry, releasing the slot if it still points back.\n\nsrc/overlays/l14/unclassified_002df080.c\n- FUN_L14_002df080 (180 B) -- initialises two tables of spaced vectors and clears four fields.\n- FUN_L14_002dfc58 (184 B) -- builds the effect request on the stack and submits it when the clip-volume check passes.\n- FUN_L14_002ef630 (192 B) -- rebuilds the 11 vectors of a table entry.\n\nAll four are ported from rac1-decomp (PAL), where their bodies are exact. Every reference was re-anchored on this build by position against the retail disassembly (no address is transposed: the PAL core data sits 0x100 above ours, so their D_0013E633 + 0x1D is our D_0013E550), and each body was re-checked byte for byte on the game compiler route (cc1 sce-991111b + GNU as, -O2 -G2). progress/report.json regenerated with scripts/gen_progress_report.py.\n\n(cherry picked from commit 0722f18f11552f7c76f422eb290db0c730451b15)\n\n* overlay: promote FUN_L14_002aead8, ported from rac1-decomp (200 B)\n\nunclassified_002460f8.c\n- FUN_L14_002aead8 (200 B) -- checks a flag and a position test, then sets up three vectors in the moby data; the 16-byte copy is the qcopy idiom.\n\nPorted from rac1-decomp (PAL, vendor_002ACCC0.c: func_L14_002AFD18), exact there. Measured here on the ee-as route: this body reads one datum gp-relatively (D_L14_0016139C), and the game compiler's own as expands a bare symbol absolutely -- ee-as (SN ProDG, docs/TOOLCHAIN.md) expands it to R_MIPS_GPREL16, which is what retail has. progress/report.json regenerated.\n\n(cherry picked from commit 829f6172af6fe8037b328a17a80deec67e71229d)\n\n* overlay: promote FUN_L14_002aea08 and FUN_L14_002aed50, ported from rac1-decomp (420 B)\n\nunclassified_002460f8.c\n- FUN_L14_002aea08 (208 B) -- per-frame update of a moby's aim and turn state from level tuning constants; all ten constants are gp-relative.\n- FUN_L14_002aed50 (212 B) -- advances the blink phase and fades each light entry's alpha up and down; its counter and 1.0f constant are gp-relative.\n\nBoth ported from rac1-decomp (PAL), exact there, re-anchored here by position and re-checked byte for byte. Both need ee-as (SN ProDG) to assemble, for the same reason as FUN_L14_002aead8: the game compiler's own as expands a bare small-data symbol absolutely, ee-as expands it to R_MIPS_GPREL16. progress/report.json regenerated.\n\n(cherry picked from commit f87c75113e5534d3f3439230d2b0d3edf550d246)\n\n* overlay: declare the Oltanis small-data constants with the sda attribute\n\nThe three functions FUN_L14_002aead8, FUN_L14_002aea08 and FUN_L14_002aed50\ndeclared their $gp-relative constants as bare 'extern s16' read through\ncasts, relying on a -G2 GNU assembler to classify them as small data. On the\nbuild's own route (game cc1 + Ps2EeAs, the single-pass assembler) that leaves\nthem absolute and the three bodies prove SIZE 204/200, 236/208 and 220/212.\nDeclared with their real types and __attribute__((sda)), as the other\noverlay units do, all seven C functions of the file prove EXACT on the game\nroute (decomp overlays check: 7/7), so no other assembler is needed; the\ncomments saying so are corrected.\n\n(cherry picked from commit 9bcadc03ee9b223266ef9ccd1a81148b72b5b101)\n\n* overlay: refresh the progress map for the Oltanis promotions\n\nassets/decomp_map.svg and decomp_map.json regenerated with\nscripts/generate_treemap.py from the committed progress/report.json after the\nseven level-14 promotions.\n\n---------\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":13.524944,"total_code":3558980,"matched_code":408568,"matched_code_percent":11.479918,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1713,"matched_functions_percent":37.789543,"complete_code":408568,"complete_code_percent":11.479918,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-10-01T06:04:41Z","commit_sha":"48d17444282497819560cfaba78dcaa41aa1a4c2","commit_message":"overlay: promote seven Oltanis functions ported from rac1-decomp (1300 B) (#40)\n\n* overlay: promote four Oltanis functions ported from rac1-decomp (680 B)\n\nsrc/overlays/l14/unclassified_002460f8.c\n- FUN_L14_002b5c98 (124 B) -- clears the moby's link to its slot entry, releasing the slot if it still points back.\n\nsrc/overlays/l14/unclassified_002df080.c\n- FUN_L14_002df080 (180 B) -- initialises two tables of spaced vectors and clears four fields.\n- FUN_L14_002dfc58 (184 B) -- builds the effect request on the stack and submits it when the clip-volume check passes.\n- FUN_L14_002ef630 (192 B) -- rebuilds the 11 vectors of a table entry.\n\nAll four are ported from rac1-decomp (PAL), where their bodies are exact. Every reference was re-anchored on this build by position against the retail disassembly (no address is transposed: the PAL core data sits 0x100 above ours, so their D_0013E633 + 0x1D is our D_0013E550), and each body was re-checked byte for byte on the game compiler route (cc1 sce-991111b + GNU as, -O2 -G2). progress/report.json regenerated with scripts/gen_progress_report.py.\n\n* overlay: promote FUN_L14_002aead8, ported from rac1-decomp (200 B)\n\nunclassified_002460f8.c\n- FUN_L14_002aead8 (200 B) -- checks a flag and a position test, then sets up three vectors in the moby data; the 16-byte copy is the qcopy idiom.\n\nPorted from rac1-decomp (PAL, vendor_002ACCC0.c: func_L14_002AFD18), exact there. Measured here on the ee-as route: this body reads one datum gp-relatively (D_L14_0016139C), and the game compiler's own as expands a bare symbol absolutely -- ee-as (SN ProDG, docs/TOOLCHAIN.md) expands it to R_MIPS_GPREL16, which is what retail has. progress/report.json regenerated.\n\n* overlay: promote FUN_L14_002aea08 and FUN_L14_002aed50, ported from rac1-decomp (420 B)\n\nunclassified_002460f8.c\n- FUN_L14_002aea08 (208 B) -- per-frame update of a moby's aim and turn state from level tuning constants; all ten constants are gp-relative.\n- FUN_L14_002aed50 (212 B) -- advances the blink phase and fades each light entry's alpha up and down; its counter and 1.0f constant are gp-relative.\n\nBoth ported from rac1-decomp (PAL), exact there, re-anchored here by position and re-checked byte for byte. Both need ee-as (SN ProDG) to assemble, for the same reason as FUN_L14_002aead8: the game compiler's own as expands a bare small-data symbol absolutely, ee-as expands it to R_MIPS_GPREL16. progress/report.json regenerated.\n\n* overlay: refresh the progress map for the seven Oltanis promotions\n\nRegenerated with scripts/generate_treemap.py from progress/report.json, as CONTRIBUTING.md now asks (assets/decomp_map.svg and assets/decomp_map.json).\n\n---------\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":13.524944,"total_code":3558980,"matched_code":408568,"matched_code_percent":11.479918,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1713,"matched_functions_percent":37.789543,"complete_code":408568,"complete_code_percent":11.479918,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-10-01T05:26:16Z","commit_sha":"8d33de8f171e1840958d6a08668a7eea88ca012a","commit_message":"docs: add one-command contributor setup (setup.sh) (#30)\n\n* docs: add one-command contributor setup (setup.sh)\n\nsetup.sh installs the whole toolchain from pinned public downloads (SHA-256 checked), builds the game compiler from its GPL source and the patches/sce-991111b stack with the new scripts/build-game-compiler.py, takes the boot ELF from the contributor's own disc image, and runs the gate. Linux and WSL run natively; macOS and other hosts run the same script in an Ubuntu container (--docker, --shell). The retail game code needs the ProDG 3.01 EE assembler (ps2eeas 1.9.25.758), fetched from its public mirror. verify-baseline.sh and check-unit.py find the R5900 binutils inside the checkout. README gains a Quick setup section; CONTRIBUTING and docs/building.md point at it.\n\n* docs: slim the quick setup section and harden setup.sh\n\nREADME keeps only the commands and the platform table; the licence and footprint details move to docs/building.md. setup.sh mounts the disc image and executable read-only in Docker mode instead of copying them, keeps a replaced tools/ directory as .previous instead of deleting it, and expands empty arrays in a way bash 3.2 (macOS) accepts.\n\n* fix: make the quick setup work on a WSL checkout (#35)\n\n* fix: apply the patch stack from the repository root\n\n* fix: pass Unix paths to the PE tools under wine\n\n* fix: install wine when the checkout is not on a Windows drive\n\n---------\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>\n\n* docs: regenerate the progress map alongside the progress report\n\nContributors regenerate progress/report.json with each promotion but the\nmap (assets/decomp_map.svg, .json) was left to the maintainer. Add the\ngenerate_treemap.py step to the promotion checklist and list it next to\nmake progress in docs/building.md.\n\n* docs: keep the README quick setup to the two commands\n\nMove the platform table, the --elf/--check/--help notes and the PASS line\ninto a Quick setup section at the top of docs/building.md; the README keeps\nthe clone + setup.sh lines and a link. CONTRIBUTING now points at the new\nsection.\n\n---------\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@hotmail.com>\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":13.488417,"total_code":3558980,"matched_code":407268,"matched_code_percent":11.443391,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1706,"matched_functions_percent":37.63512,"complete_code":407268,"complete_code_percent":11.443391,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-10-01T05:16:14Z","commit_sha":"4c0506831882c59b9ac18c90f310af2e99ca45cd","commit_message":"overlay: refresh the progress map for the Oltanis promotions (#39)\n\nRegenerated with scripts/generate_treemap.py from the committed\nprogress/report.json; picks up the five functions promoted in #37\n(406,848 -> 407,268 B matching C).","measures":{"fuzzy_match_percent":13.488417,"total_code":3558980,"matched_code":407268,"matched_code_percent":11.443391,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1706,"matched_functions_percent":37.63512,"complete_code":407268,"complete_code_percent":11.443391,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-10-01T04:12:41Z","commit_sha":"1dc60974d7dbbc0b55191aebdac8ca4dd1495de0","commit_message":"overlay: promote five Oltanis functions (420 B) (#37)\n\n* overlay: promote FUN_L14_003135b8 and FUN_L14_003167e0 (116 B)\n\nBoth bodies are written from the retail disassembly of the level-14 program\nand reproduce it byte for byte.  Verified with the game compiler route\n(cc1 sce-991111b + GNU as, -O2 -G2) and, independently, with the SN\ncompiler (ee-gcc2953, -O2 -G2): same 80 + 36 bytes either way.\n\nThe two functions were picked because their boundaries agree with\nconfig/overlays/us/level-14.json: same start and same size as this\ncatalogue.  Reference data uses the level's naming: D_L14_00167500 is\nabove 0x15EF00 (level data), D_001413DC is below it (executable data).\n\nThe report was regenerated with scripts/gen_progress_report.py (no build\nneeded) and --check passes.  make overlays and make elf were NOT run here:\nthat needs the game data and the baseline build, which this checkout does\nnot have.\n\n* overlay: promote FUN_L14_002b44a8 and FUN_L14_002bb4d8 (176 B)\n\nTwo more Oltanis bodies, written from the retail disassembly and byte for\nbyte with it on the game compiler route (cc1 sce-991111b + GNU as,\n-O2 -G2).  Both boundaries agree with config/overlays/us/level-14.json:\nsame start and same size.\n\nFUN_L14_002b44a8 walks the record list at D_L14_001ABF40[index] until the\nterminating negative entry and flags the objects whose state byte is 1.\nThe list read is unsigned in the body and signed in the loop test, which\nis what retail does (lhu, then lh twice).\n\nFUN_L14_002bb4d8 releases the handle at 0x12 of the record and hands the\nmoby to FUN_0020c828 (mark_moby_for_removal).\n\nThe two callees are named as the tree names them, not by their level\naddress: FUN_L00_0023e838 is the shared function at 0x002463C8 here, and\nFUN_0020c828 is the executable function at 0x00257068 here.\n\nThe report was regenerated with scripts/gen_progress_report.py and --check\npasses.  make overlays and make elf were NOT run in this checkout.\n\n* overlay: promote FUN_L14_00306158 (128 B)\n\nOltanis vendor: allocate 0x574 bytes, copy the two 16-byte records out of\nthe caller, stamp the header fields and hand the allocation to the level's\npost-create hook; return the allocation.\n\nThe two 16-byte copies go through $2 with each address in its own register\nat offset 0, which is the qcopy idiom of include/qcopy.h -- the header\nrecords that all 154 adjacent lq/sq copies in the retail game code have\nthat shape and that no plain C copy reproduces it (a TImode or aligned\nstruct copy folds the offset into lq/sq).\n\nByte for byte with retail on the game compiler route (cc1 sce-991111b +\nGNU as, -O2 -G2), and the boundary agrees with\nconfig/overlays/us/level-14.json (same start, same size).\n\nThe report was regenerated and --check passes; test_public_tools.py is\ngreen.  make overlays and make elf were NOT run in this checkout.\n\n---------\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":13.488417,"total_code":3558980,"matched_code":407268,"matched_code_percent":11.443391,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1706,"matched_functions_percent":37.63512,"complete_code":407268,"complete_code_percent":11.443391,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-10-01T03:58:54Z","commit_sha":"0c05b149a07e78ef81baab1608f3db034f7affac","commit_message":"docs: name the memory-card state handlers in the recovered-name catalog (#33)\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":13.476616,"total_code":3558980,"matched_code":406848,"matched_code_percent":11.43159,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1701,"matched_functions_percent":37.52482,"complete_code":406848,"complete_code_percent":11.43159,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-10-01T03:56:12Z","commit_sha":"f11b974e1ab83071ce1e3cfb53823b0cde89d998","commit_message":"fix: read alias declarations that carry a parameter list (#34)\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":13.476616,"total_code":3558980,"matched_code":406848,"matched_code_percent":11.43159,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1701,"matched_functions_percent":37.52482,"complete_code":406848,"complete_code_percent":11.43159,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-10-01T03:54:53Z","commit_sha":"d5146f24778ba444a6809cceac34095f57eb2cc7","commit_message":"docs: point the contributing build step at the build guide (#32)\n\nCo-authored-by: Louis-Philippe Le Sieur <llesieur99@users.noreply.github.com>","measures":{"fuzzy_match_percent":13.476616,"total_code":3558980,"matched_code":406848,"matched_code_percent":11.43159,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1701,"matched_functions_percent":37.52482,"complete_code":406848,"complete_code_percent":11.43159,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-09-30T19:28:55Z","commit_sha":"bdda5431115055340d0638b9138681bd81814dfa","commit_message":"overlay: decompile 94 more shared veldin functions, migrate 91 level functions (#29)\n\n* overlay: migrate 26 exact level functions; start the second shared veldin batch\n\n* overlay: migrate 65 more exact overlay functions\n\n* overlay: decompile 30 more shared functions from veldin (level 00)\n\n* overlay: regenerate progress\n\n* overlay: decompile 11 more shared functions from veldin (level 00)\n\n* overlay: decompile 29 more shared functions from veldin (level 00)\n\n* overlay: regenerate progress","measures":{"fuzzy_match_percent":13.476616,"total_code":3558980,"matched_code":406848,"matched_code_percent":11.43159,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1701,"matched_functions_percent":37.52482,"complete_code":406848,"complete_code_percent":11.43159,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":105}},{"timestamp":"2026-09-30T16:52:45Z","commit_sha":"67ca64a137512a3fa786a4592f3865a4a2921b5d","commit_message":"docs: fix link to bordplate/RC1 in README.md","measures":{"fuzzy_match_percent":11.526619,"total_code":3558980,"matched_code":337448,"matched_code_percent":9.481593,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1517,"matched_functions_percent":33.465694,"complete_code":337448,"complete_code_percent":9.481593,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":102}},{"timestamp":"2026-09-30T16:51:36Z","commit_sha":"2033dc2ed600a33b6c1a5a134c91155f06dd8064","commit_message":"docs: refine README language for clarity and precision\n\nUpdated wording for clarity and improved phrasing in the README.","measures":{"fuzzy_match_percent":11.526619,"total_code":3558980,"matched_code":337448,"matched_code_percent":9.481593,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1517,"matched_functions_percent":33.465694,"complete_code":337448,"complete_code_percent":9.481593,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":102}},{"timestamp":"2026-09-30T15:50:41Z","commit_sha":"e301c3d535558cb6382e7bfd412dfbdcf0357f67","commit_message":"overlay: decompile shared functions from veldin (level 00) (#28)\n\n* overlay: decompile 29 shared functions from veldin (level 00)\n\n* overlay: regenerate progress for the shared veldin functions\n\n* overlay: decompile 35 more shared functions from veldin (level 00)\n\n* overlay: decompile 28 more shared functions from veldin (level 00)\n\n* overlay: regenerate progress for the shared veldin functions\n\n* overlay: decompile 103 more shared functions from veldin (level 00)\n\n* overlay: regenerate progress for the shared veldin functions\n\n* overlay: decompile 22 more shared functions from veldin (level 00)\n\n* overlay: slightly thicker outline on the boot ELF text, regenerate progress\n\n* overlay: decompile 92 more shared functions from veldin (level 00)\n\n* overlay: regenerate progress for the shared veldin functions\n\n* overlay: decompile 24 more shared functions from veldin (level 00)\n\n* overlay: regenerate progress for the shared veldin functions","measures":{"fuzzy_match_percent":11.526619,"total_code":3558980,"matched_code":337448,"matched_code_percent":9.481593,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1517,"matched_functions_percent":33.465694,"complete_code":337448,"complete_code_percent":9.481593,"complete_data":0,"complete_data_percent":0,"total_units":466,"complete_units":102}},{"timestamp":"2026-09-30T13:52:12Z","commit_sha":"034a49ab2b9d4d5d33d4de779c677889ef16505b","commit_message":"overlay: decompile novalis (level 01) (#26)\n\n* docs: thinner outline around the BOOT ELF percentage on the progress map\n\nThe centered percentage and its caption had a 5/4 px dark stroke that read\nas a heavy black border. Now 2 px at lower opacity; still legible over the\ntreemap.\n\n* overlay: first 10 novalis (level 01) functions in c\n\nFUN_L01_0026eff8, 002f4348, 002f60f8, 002f81c8, 002f9000, 002fac80,\n002ffa90, 00307c48, 00309bf8, 00309c98: 1,216 bytes, each proved byte for\nbyte at its level address (overlay-place-bytes-v1).\n\n* overlay: 8 more novalis (level 01) functions in c; progress report\n\nFUN_L01_00287b00, 00287c80, 002f68a0, 002ffcd0, 00302328, 0030be70,\n0030f0e0, 0030f208, each proved byte for byte at its level address. The\ntwo particle spawners now share one Particle layout.\n\n* overlay: 6 more novalis (level 01) functions in c; progress report\n\n* overlay: 6 more novalis (level 01) functions in c; progress report\n\n* overlay: 5 more novalis (level 01) functions in c; progress report\n\n* overlay: one more novalis (level 01) function in c; progress report","measures":{"fuzzy_match_percent":9.456025,"total_code":3558980,"matched_code":263756,"matched_code_percent":7.411,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1254,"matched_functions_percent":27.6638,"complete_code":263756,"complete_code_percent":7.411,"complete_data":0,"complete_data_percent":0,"total_units":468,"complete_units":91}},{"timestamp":"2026-09-30T13:32:15Z","commit_sha":"5e0c342551c0adbe21e0e1fda3f89e84f6d5e4e7","commit_message":"docs: fix typo in README regarding AI project description","measures":{"fuzzy_match_percent":8.985778,"total_code":3558980,"matched_code":247020,"matched_code_percent":6.940753,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1216,"matched_functions_percent":26.825502,"complete_code":247020,"complete_code_percent":6.940753,"complete_data":0,"complete_data_percent":0,"total_units":468,"complete_units":91}},{"timestamp":"2026-09-30T13:22:19Z","commit_sha":"477ec6104513905a2ffa4a6578c18a4b5b0ca98f","commit_message":"overlay: decompile veldin (level 00) (#27)\n\n* overlay: first veldin (level 00) function in c; progress report\n\n* overlay: 3 more veldin (level 00) functions in c; progress report\n\n* overlay: 3 more veldin (level 00) functions in c; progress report\n\n* overlay: 3 more veldin (level 00) functions in c; progress report\n\n* overlay: last veldin (level 00) function in c; progress report","measures":{"fuzzy_match_percent":8.985778,"total_code":3558980,"matched_code":247020,"matched_code_percent":6.940753,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1216,"matched_functions_percent":26.825502,"complete_code":247020,"complete_code_percent":6.940753,"complete_data":0,"complete_data_percent":0,"total_units":468,"complete_units":91}},{"timestamp":"2026-09-30T08:56:33Z","commit_sha":"bfca68640cc7263196b9feee722c8256292b2b8d","commit_message":"decomp: 34 exact units (8 from the boot ELF split, 26 cut out of the textbin gaps) and 35 recovered unit names (63.07 % -> 64.58 %) (#25)\n\n* decomp: 8 exact units banked by the boot ELF split (63.07 % -> 64.51 %)\n\nPromote the byte-exact sources the three split threads left in the banks:\nsce_tty_handler (sdk-compiler), parse_bin, init_once, process_pad_input,\nfun_00219e10, fun_001fb440, fun_001fb740 and snd_play_vag_stream_by_loc_ex_cb\n(game-compiler). Each was re-proved on its provenance compiler with the score\ncache off before promotion. init_once's switch table is placed by a\nRODATA_OVERLAYS entry at 0x1E7B30.\n\nThe gate caught one thing the per-unit proof cannot: init_once stored\nD_0015EE90 and D_0015ED80 in the wrong order, and since only the second\nstore (the one in the jal delay slot) comes out gp-relative, the two words\ndiffered in the linked ELF while the relocation-masked proof read exact.\nWriting the D_0015ED80 store first gives retail's EE90-absolute, ED80-gp pair.\n\nBoot executable: 214 216 -> 219 080 exact bytes of 339 628 (63.07 % -> 64.51 %),\n1012 -> 1020 exact functions. verify-baseline.sh PASS, built SHA-256\ne050581032e4bb3f20341307da5b69b76f1574910519155380ea771e55c3c0c9.\n\n* chore: regenerate progress report\n\n* decomp: name 35 pending units after their recovered symbols\n\nThe pending units at 0x1204b8 and 0x1efa68-0x237370 that still carried\nfun_<address> leaves have recovered names in config/us/recovered_names.json\n(the same names bordplate/RC1 uses in its symbol table); the neighbouring\nunits (fast_vec_dot, fast_vec_cross, fast_dec_timer) were already named from\nthat source. Give the rest the same lower_snake_case names in place:\nreset_vif1_gif, coll_line_fix, fast_intersect_vert, scis_and_render,\nfast_dec_timer_s16, log2dim, fast_mem_zero16, fast_mem_copy, fast_mem_or16,\nfast_vec_add/sub/scale/length/dist/normalize, fast_vector_to_packed_chars,\nfast_arc_tan, fast_bsphere_check, draw_boot_image, fast_decompress,\nupdate_moby_grids, moby_proc, create_part, update_parts, part_load_tex,\nshrub_proc, build_shrub_texture_dma, ssp_load_tex, sky_bsphere_check,\ncompute_tfrag_texture_usage, light_tfrags, tie_proc, build_tie_texture_dma,\nlight_ties.\n\nDirectories are unchanged, so no compiler route moves. The unit table, the\ncategory list, recovered_names.json and the overlay catalogue's exe-unit\ncolumn follow the new paths. verify-baseline.sh PASS, built SHA-256 unchanged.\n\n* fix: rename proposals follow the renamed pending units' source paths\n\n* decomp: 26 small functions cut out of the textbin gaps, all byte-exact (64.51 % -> 64.58 %)\n\nTwelve textbin gaps held 26 functions nobody had cut into units yet: 8 to\n68 bytes each, menu callbacks and state helpers around 0x207630-0x208f00 and\n0x21a1b0-0x2223d8, plus the MPEG DMA restart callback at 0x23d110.\nsplit-gap-functions.py cuts them out of the gap rows (each checked to lie in\none gap and end in jr $ra), adds them to ghidra_functions.csv, and lets\nvideo_dec_create call FUN_0023d110 by name instead of the gap's data label.\n\nEvery one of the 26 is promoted as exact C (game-compiler, no flags), 692\nbytes in total, which the gaps did not count before. Four needed a second\nspelling: fun_002223d8's three zero stores written (0x10, 0x14, 0xF) so the\ncompiler emits them in retail's order; fun_00208eb8 reads its flag through\nthe menu base (`*(int *)(D_0013D290 + 0x1C)`) so the base stays in v0;\nfun_002089a8 writes its two -1 stores DC then E0 (same-value stores come out\nreversed) with the EEB0 store between them; fun_002088a8 uses a struct with\nnamed fields so the address is hoisted the way retail has it.\n\nBoot executable: 219 080 / 339 628 -> 219 772 / 340 320 exact bytes\n(64.51 % -> 64.58 %), 1020 -> 1046 exact functions. verify-baseline.sh PASS,\nbuilt SHA-256 e050581032e4bb3f20341307da5b69b76f1574910519155380ea771e55c3c0c9.\n\n* chore: regenerate progress report","measures":{"fuzzy_match_percent":8.769985,"total_code":3558980,"matched_code":238840,"matched_code_percent":6.710912,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4533,"matched_functions":1205,"matched_functions_percent":26.582836,"complete_code":238840,"complete_code_percent":6.710912,"complete_data":0,"complete_data_percent":0,"total_units":468,"complete_units":89}},{"timestamp":"2026-09-30T08:07:08Z","commit_sha":"211aec16b5a11024313fd422a5210df21828f189","commit_message":"docs: restyle the progress map to match the logo (#24)\n\n* docs: restyle the progress map to match the logo\n\nHalve the boot ELF drawer, move the whole palette to the logo's orange\n(#e0852e) and warm gunmetal greys, and dim the drawer's treemap less while a\nsoft local shadow keeps its percentage legible.\n\n* docs: brighten the progress map toward the logo orange\n\nUse the logo's average orange (#de812f) and its darker tone for partial\ncopper, lighten the drawer face and dim its treemap less (75 %), with a\nstronger local shadow behind the percentage.\n\n* docs: drop the map title and give the README a progress heading\n\nRemove the title line and bolt mark from the map, restore the neutral white\ntext colours, and rework the README intro: an AI note, the warning above the\nprogress map, and a Decompilation progress heading.\n\n* docs: move the function count to the top line of the map\n\n* docs: reword the README AI note\n\n* docs: tighten the dash in the README AI note","measures":{"fuzzy_match_percent":8.690601,"total_code":3558288,"matched_code":233284,"matched_code_percent":6.556074,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4507,"matched_functions":1171,"matched_functions_percent":25.981806,"complete_code":233284,"complete_code_percent":6.556074,"complete_data":0,"complete_data_percent":0,"total_units":468,"complete_units":87}},{"timestamp":"2026-09-30T05:12:02Z","commit_sha":"49472fd268c769077cf42c65456ff79c1d08ffc5","commit_message":"docs: update README with decompilation progress image","measures":{"fuzzy_match_percent":8.690601,"total_code":3558288,"matched_code":233284,"matched_code_percent":6.556074,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4507,"matched_functions":1171,"matched_functions_percent":25.981806,"complete_code":233284,"complete_code_percent":6.556074,"complete_data":0,"complete_data_percent":0,"total_units":468,"complete_units":87}},{"timestamp":"2026-09-30T05:08:42Z","commit_sha":"599ab6b55a96ceaf036c878ef4f04f7e49833275","commit_message":"overlay: level code layer with catalogue, sources, proof-backed progress and 159 migrated functions (#23)\n\n* config: US level overlay function catalogue and level descriptions\n\nconfig/overlays/us/functions.tsv: every distinct function of the 19 level\nprograms (decomp overlays catalogue): 693 exe, 1959 shared (1,190,224 B),\n1379 level (2,028,412 B); names, sizes, fingerprints and places only, no\nbytes. config/overlays/us/levels.json: planet name and description per\nlevel for the progress map. config/us/overlays/ (records and generated asm,\nrestored by the tooling setup) is gitignored.\n\n* docs: level code overlays: data, measured US facts, names, proof, progress\n\ndocs/overlays.md records what the US records showed (lit at 0x15EF00, $gp\n0x166C00 in every level, record order and types, dispatch record layout,\nentry points) and how the layer is laid out here: catalogue, src/overlays/,\nthe placed-bytes proof and how overlays count in the metric.\n\n* config: overlay catalogue: a level body matching a resident function's fingerprint is level code\n\nOnly executable code from 0x15EF00 up is replaced by a level and can reappear\nthere as the same function; five 8- and 12-byte level bodies whose masked\nfingerprint equalled a resident (SDK) function's are distinct copies and are\ncatalogued as shared functions now: 691 exe, 1961 shared, 1379 level rows.\n\n* chore: level overlay sources: INCLUDE_ASM stubs and the overlays build target\n\nsrc/overlays/shared/ and src/overlays/lNN/: 351 files of INCLUDE_ASM stubs for\nthe 3340 shared and level functions, in link order, each file named after the\nexecutable unit it follows; a stub is replaced by C when a function is proved\nexact. configure.py --overlays writes build/overlays/build.ninja and\nmake overlays compiles every file with the game compiler's driver into\nbuild/overlays/obj/; nothing is linked and the executable build, its\nbuild.ninja and verify-baseline.sh are untouched (gate: PASS).\n\n* chore: progress report and map count the level overlays\n\n- overlay_units.py: the shared and level functions as progress units from\n  config/overlays/us/functions.tsv and src/overlays/ (C = matched, stub =\n  pending), no retail bytes needed, so --check works from the repository.\n- gen_progress_report.py: overlay units grouped by file; categories boot\n  (= game + sdk), overlays (= shared + levels) and level_NN; the top-level\n  measures cover executable and overlays together.\n- generate_treemap.py: the map is the executable as a drawer (its own\n  C_EXACT over its dimmed group treemap) above a tree of the shared code and\n  the 19 levels with planet, description, percentage and per-file blocks;\n  height follows the branch count; assets/decomp_map.json schema\n  rnc-public-progress-v3 with boot, overlays and total.\n- test_public_tools.py: the boot category on executable units, one test for\n  the overlay units (78 tests pass).\n\n* docs: overlay build, proof and progress rules\n\ndocs/overlays.md: make overlays (configure.py --overlays, game cc1 + GNU as,\nnothing linked), the proof on the game compiler route, the catalogue rule for\nresident fingerprint collisions and the refreshed counts.\ndocs/progress-metrics.md: the overlays are in scope and in the headline\nnumber; how they are counted (once each, C in src/overlays is exact, stubs\ncarry no C_FUZZY); the new map and the report categories.\n\n* decomp: 159 level overlay functions migrated into src/overlays\n\nFunctions whose C was already matched elsewhere were migrated, renamed to\nthe US names and proved on the game route at their canonical addresses\n(overlay-place-bytes-v1); the 159 that came out byte for byte replace\ntheir INCLUDE_ASM stubs, 145 of them shared code present in every level.\nEach unit file was re-proved after the splice and builds under make\noverlays.\n\n* chore: regenerate progress report and map for the ported overlay functions\n\noverlay_units.py: an overlay function is C when its definition is in\nsrc/overlays, not when a unit file only declares it (26 prototypes of\nfunctions still stubbed elsewhere were counted). Total C_EXACT 5.74 %\n(executable 54.48 %, overlays 0.59 %: 19,068 of 3,218,660 B).\n\n* chore: progress map without the drawer handle, shorter captions, one-line footer\n\nThe boot ELF drawer loses the handle bar and its treemap fills the drawer;\nthe line under the title counts functions in C, the hero and drawer\npercentages get short captions, and the footer is one line (executable,\noverlays, bytes in C) so the numbers read at a glance.\n\n* chore: progress map: warm sharp-cornered drawer, legend centred in the header\n\nThe executable's drawer drops the blue face and rounded corners for a\ndim amber face edged in the bolt orange (the page is already blue-black);\nthe three legend rows sit with equal room above and below.\n\n* chore: add the overlay commit type\n\nLevel overlay work (catalogue, src/overlays/, the overlays build, its map\nand report plumbing) gets its own type, overlay:, in the standard and in\nthe commit-msg hook; decomp: stays the executable's.\n\n* overlay: progress map set in RG Future, drawer without a border\n\nThe two RG Future faces (assets/fonts/, regular and italic) are embedded in\nthe SVG as data URLs so the map renders the same wherever it is shown as an\nimage; glyphs the font lacks fall back to the system sans-serif. Italic for\nthe title tail and the planet descriptions; the smallest texts one point\nlarger for the display face. The boot ELF drawer loses its outline.\n\n* overlay: progress map back in the system font, drawer still without a border\n\nReverts the RG Future embedding (the font files, the @font-face style, the\nitalics and the size bump) at the owner's request; the boot ELF drawer keeps\nno outline.\n\n* overlay: progress map drawer without a frame, the treemap fills it edge to edge","measures":{"fuzzy_match_percent":8.690601,"total_code":3558288,"matched_code":233284,"matched_code_percent":6.556074,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":4507,"matched_functions":1171,"matched_functions_percent":25.981806,"complete_code":233284,"complete_code_percent":6.556074,"complete_data":0,"complete_data_percent":0,"total_units":468,"complete_units":87}},{"timestamp":"2026-09-30T04:57:06Z","commit_sha":"2939d45044379aff9673f68e7527664879b99071","commit_message":"decomp: playbook wave to 63.1% C_EXACT (#22)\n\n* decomp: 9 new exact units (near misses, sky shells, glyph printer, sprite quad)\n\n* chore: regenerate progress report (54.48% -> 56.99% C_EXACT)\n\n* fix: padless-asm finish rebases GPREL16 addends of undeclared externals\n\nPs2EeAs relaxes a MACRO_ADDR load in a delay slot to $gp and stores -gp0 as\nthe addend when the external has no .extern size, so GNU ld reported\n'relocation truncated to fit: R_MIPS_GPREL16'. finish now adds gp0 back for\nnon-local, undefined, size-0 symbols only (sized .extern symbols already carry\ncorrect addends). No existing object changes; the gate passes.\n\n* decomp: fun_00226fb8 exact (MACRO_ADDR vector base, needs the GPREL16 finish fix)\n\n* chore: regenerate progress report (fun_00226fb8)\n\n* decomp: 4 new exact units (update_help_state, poll_pad_device_state, fun_001f76a0, draw_textured_quad)\n\n* chore: regenerate progress report (57.08% -> 58.24% C_EXACT)\n\n* decomp: memcard_update_state exact (6100 B hand seed, six jump tables via RODATA_OVERLAYS 0x1E8200)\n\n* chore: regenerate progress report (58.24% -> 60.03% C_EXACT)\n\n* decomp: do_space_transition, sound_stop_all_sounds exact; 11 byte-exact units rewritten without inline asm\n\n* chore: regenerate progress report (60.03% -> 61.81% C_EXACT)\n\n* decomp: 27 byte-exact units rewritten without inline asm\n\n* chore: regenerate progress report (61.81% -> 63.07% C_EXACT)","measures":{"fuzzy_match_percent":85.43719,"total_code":339628,"matched_code":214216,"matched_code_percent":63.073715,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1167,"matched_functions":1012,"matched_functions_percent":86.71808,"complete_code":214216,"complete_code_percent":63.073715,"complete_data":0,"complete_data_percent":0,"total_units":116,"complete_units":74}},{"timestamp":"2026-09-29T17:45:22Z","commit_sha":"6f182821f5e160601c69c0e353b1e2c870477f12","commit_message":"decomp: 28 exact units from the playbook run (PAL twins + large hand seeds) (#21)\n\n* decomp: 4 PAL twin ports exact (decode_bitstream_0, fun_00207650, fun_00221af0, fun_0023a2c0)\n\nPorted from rac1-decomp (55f1201). Three functions were split out of text\ngaps (fun_00207650, fun_00221af0, fun_0023a2c0) and fun_00218f98 now names\nFUN_0023a2c0 instead of a data symbol. All four proven with retail relink;\nfull-ELF gate PASS.\n\n* chore: regenerate progress report\n\nC_EXACT 48.40% -> 48.58% (165008 / 339628 B).\n\n* decomp: 5 large units exact from hand seeds (occlusion, effects, 3 menu units)\n\nbuild_occlusion_visibility, fun_001edc50, fun_0021d948, fun_002192a8 and\nfun_00216c48, written from the listing (structs, loop forms, call order),\nthen sweeps and auto. 5132 bytes; fun_00216c48 is self-recursive with a\nplaced jump table, proven by the extended retail byte check. Full-ELF\ngate PASS.\n\n* chore: regenerate progress report\n\nC_EXACT 48.58% -> 50.10% (170140 / 339628 B).\n\n* decomp: 15 new exact units from porcja B (hand seeds and PAL twin ports)\n\ncreate_point_light, snd_flush_sound_commands, sce_ipu_init, fun_00204e30,\nfun_002316e8, fun_0022f5b0, vu1_set_scissor, fun_00204cf0, fun_0020bf90,\n_PES_packet, fun_00214598, fun_002389e0, fun_0021d4a8, draw_rect_overlay,\ndraw_debug_profiler. Each byte-exact on its provenance compiler with the\nretail relink proof; make elf gate PASS (SHA e0505810...c0c9).\n\nC_EXACT 50.10% -> 53.59% (170140 -> 182000 of 339628 bytes, +11860),\nfunctions 938 -> 953 of 1167.\n\n* chore: regenerate progress report\n\nC_EXACT 50.10% -> 53.59% (+11860 bytes, 15 units).\n\n* decomp: 4 exact units (pause_all_sounds, draw_missions_menu2, saving_data_menu2, fun_002223f0)\n\nHand seeds from the listing (porcja A). fun_002223f0 gets its switch table through RODATA_OVERLAYS. Gate PASS.\n\n* chore: regenerate progress report","measures":{"fuzzy_match_percent":83.39675,"total_code":339628,"matched_code":185028,"matched_code_percent":54.479607,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1167,"matched_functions":957,"matched_functions_percent":82.00514,"complete_code":185028,"complete_code_percent":54.479607,"complete_data":0,"complete_data_percent":0,"total_units":115,"complete_units":67}},{"timestamp":"2026-09-29T14:54:54Z","commit_sha":"e24885934e9cbd77742d37320273a4a0daf17b8a","commit_message":"fix: zero-size alias no longer blocks check-unit; UNC paths for native WSL roots (#20)\n\ncheck-unit: a zero-size alias label (func_xxxx beside FUN_xxxx) has no body\nfor objdiff to score, so its match_percent is None and the unit could never\nbe promotable. Such rows are now ignored by the verdict and the pairing note.\n\nconfigure: _win_path turned a native WSL path into a rootless backslash path\nthe SN driver cannot open. Under WSL it now emits a \\\\wsl.localhost UNC path,\nso BASELINE_ROOT can live on ext4 as the README recommends.\n\nRefs #9","measures":{"fuzzy_match_percent":80.281364,"total_code":339436,"matched_code":164380,"matched_code_percent":48.42739,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1164,"matched_functions":929,"matched_functions_percent":79.811,"complete_code":164380,"complete_code_percent":48.42739,"complete_data":0,"complete_data_percent":0,"total_units":115,"complete_units":66}},{"timestamp":"2026-09-29T06:37:08Z","commit_sha":"1566c2f07bc51b8745ae39f85916ceb0e9026ce3","commit_message":"decomp: 8 new exact units; qzero() macro for sq $0 (#19)\n\n* decomp: fun_00218d10 exact; qzero() macro for the sq $0 that GCC cannot emit\n\n* docs: qzero.h is approved beside qcopy.h in the non-label asm rule\n\n* decomp: 5 new exact units (fun_00218f98, fun_00218888, fun_00214e58, fun_001f2260, fun_0022b288)\n\nPromoted from hand seeds written from the listing, then finished with\nscripts/decomp auto. fun_0022b288 owns its switch table through a\nRODATA_OVERLAYS entry. make elf reproduces the retail boot ELF.\n\n* chore: regenerate progress report\n\n* decomp: double_is_not_nan and classify_float_bits exact\n\nBoth are fdlibm routines: word access through the ieee_double_shape_type\nunion in the original do { } while (0) macro shape, and classify_float_bits\ntakes an f64 argument. make elf reproduces the retail boot ELF.\n\n* chore: regenerate progress report","measures":{"fuzzy_match_percent":80.281364,"total_code":339436,"matched_code":164380,"matched_code_percent":48.42739,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1164,"matched_functions":929,"matched_functions_percent":79.811,"complete_code":164380,"complete_code_percent":48.42739,"complete_data":0,"complete_data_percent":0,"total_units":115,"complete_units":66}},{"timestamp":"2026-09-28T18:19:51Z","commit_sha":"6ccea4b89e2dcf04c51dc3a5760f433ce0f32117","commit_message":"decomp: 3 new exact units, fast link script, type header renames (#18)\n\n* chore: name include/rnc type headers after their units' subsystem paths\n\n* config: link through a derived script with unique .text input sections (link 119 s -> 2 s, same ELF)\n\n* config: fun_00208ca4 starts at 0x208CA8 (its leading nop is padding of the gap before; data points at 0x208CA8)\n\n* decomp: 3 new exact units (fun_00208ca8, queue_dma_transfer, vu1_init_chain)\n\n* chore: regenerate progress report after the 3 promoted exacts\n\n* chore: regenerate progress report","measures":{"fuzzy_match_percent":79.51448,"total_code":339436,"matched_code":161120,"matched_code_percent":47.466976,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1164,"matched_functions":921,"matched_functions_percent":79.12371,"complete_code":161120,"complete_code_percent":47.466976,"complete_data":0,"complete_data_percent":0,"total_units":116,"complete_units":66}},{"timestamp":"2026-09-28T10:13:07Z","commit_sha":"414b1e62cab3ab8bbb78b9653b8f876c839107d1","commit_message":"chore: drop the level overlays category from the progress report (boot ELF only) (#17)","measures":{"fuzzy_match_percent":79.474014,"total_code":339440,"matched_code":160852,"matched_code_percent":47.387463,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1164,"matched_functions":918,"matched_functions_percent":78.86598,"complete_code":160852,"complete_code_percent":47.387463,"complete_data":0,"complete_data_percent":0,"total_units":116,"complete_units":66}},{"timestamp":"2026-09-28T09:44:41Z","commit_sha":"89ce6ed157667968ea7299e8171e2d7844022921","commit_message":"decomp: 29 exact units, 49 files freed of inline asm, src/ organized by subsystem with 86 recovered names, compiler patch 0056 (#16)\n\n* config: drop three units that are provably C, place two switch tables\n\nintentional_asm loses three entries because a wave-2 agent reconstructed them\nas ordinary C: fun_001f99c8 and fun_001f99d0 reach 100% on the game compiler\nwith `a >= b ? a : b` under -ffast-math -fno-expensive-optimizations, and\nconvert_integer_to_float reaches 100% on sn with `return (f32)value;`. The\nplaybook states max.s/min.s are not evidence, so the first two contradicted the\nproject's own rule as well as the measurement. The units stay in the exact\nqueue; only the labels that asserted they cannot be C are gone.\n\nRODATA_OVERLAYS gains _sceFs_Rcv_Intr and fun_00216c48. Each is the sole unit\nwhose listing references its jump table (jtbl_001528E0 = 0x1528E0 and\njtbl_001E86A0 = 0x1E86A0, both from undefined_syms_auto.txt), and the offsets\nfollow the existing _dtoa_r convention (VMA - 0xFF080, verified against it).\nThis fixes table PLACEMENT so objdiff can pair; it does not by itself make\neither unit match, and fun_00216c48 additionally needs an ldl/ldr skew and a\ntrap that plain C cannot express.\n\nNOT INCLUDED: the full-ELF gate is red, and not for either of these reasons.\nverify-baseline.sh still aborts at build time on src/textbin/fun_001ec530.c.o\nwith rc=253. Diagnosis, measured: the unit compiles to a `div.s` in a branch\ndelay slot, and Ps2EeAs hard-exits 253 printing nothing when it is launched\nthrough binfmt_misc, while the same binary on the same input invoked as\n`wine Ps2EeAs.exe` warns and succeeds. So the blocker is assembler robustness\non that input, not the source shape: three source rewrites were tried and\nfalsified, including barriers that clear the `jal` slot but leave a duplicated\ndivide in a `bc1fl` slot. That needs a maintainer decision - either fix the\nsource with an accepted barrier form, or change how the build invokes the\nassembler - before anything here can be gated.\n\n* chore: regenerate progress report\n\nGenerated output from make progress, unchanged in substance: the same\n169724 / 345616 bytes (49.11%). It reflects a tree whose metrics this branch\ndoes not move - dropping three units from intentional_asm changes their\ncategory, not their bytes.\n\nThe full-ELF gate is still red and not for anything on this branch:\nverify-baseline.sh aborts at build time on src/textbin/fun_001ec530.c.o with\nrc=253, because the unit compiles to a div.s in a branch delay slot and\nPs2EeAs hard-exits without a diagnostic when launched through binfmt_misc\n(it warns and succeeds when invoked as `wine Ps2EeAs.exe`, same input).\n\n* fix: launch the Windows tools through an explicit wine\n\nThe full-ELF gate aborted at src/textbin/fun_001ec530.c.o: Ps2EeAs exits 253\nprinting nothing when binfmt_misc launches it on that unit (a div.s in a branch\ndelay slot), while `wine Ps2EeAs.exe` on the same input assembles it. The build\nnow puts `wine` in front of Ps2EeAs and the SN driver itself, except for a\ncheckout on a Windows drive under WSL (/mnt/<drive>/), where interop runs the\nPE natively as before. RNC_WINE overrides the wine binary; empty runs the PE\ndirectly.\n\n* decomp: promote seven banked exacts, each re-proved on its provenance compiler\n\nfun_0011a428 and fun_0011a448 on the SDK compiler; fun_001f7888, fun_00208b88,\nfun_00208fe8, init_moby_instance and load_hud_banks on the game compiler. No\nflags, no asm beyond name labels. load_hud_banks calls load_compressed_hud_bank\nby the FUN_00202d10 label it binds; the listing's func_00202D10 passed the\nper-unit proof but is not bound by the link.\n\n* config: drop compute_sector_index from intentional_asm\n\nThe unit was promoted to src/math/compute_sector_index.c and is covered by the\nfull-ELF gate; the entry still named its pre-promotion path.\n\n* chore: regenerate progress report\n\n* fix: count a unit as C_EXACT only when its source is C\n\nThe progress report and the map counted every promoted file as exact C,\nincluding 113 whose bytes match only through inline asm: instructions (mfc0,\nmultu, sync/ei), empty memory barriers, `__asm__(\"\" : \"+r\"(x))` scheduling\nbarriers, `.extern` directives and register pins (`register int x asm(\"v1\")`).\nThe project admits asm only as a name label and the qcopy.h idiom, so these\nunits are now pending (fuzzy 99.99) until their asm is removed.\n\nC_EXACT: 49.56 % -> 41.45 % (171 320 -> 143 256 B). C_FUZZY is unchanged.\nnon_label_asm() in rnc_units.py is the rule, mirrored in the standalone\ngenerate_treemap.py and covered by tests.\n\n* fix: build sceTtyHandler and sceIpuInit from their retail listings\n\nBoth pending units carried a hand-written copy of their assembly as a\ntop-level __asm__ block instead of the INCLUDE_ASM of the listing the gate\nextracts, unlike every other pending unit. They now include the listing; the\nfull-ELF gate still passes.\n\n* docs: the game compiler pin is host-dependent, the production stack runs through 0055\n\n* decomp: six SDK units listed as intentional asm are C\n\nquorem (newlib dtoa.c, ported from rac1-decomp) and exponent (newlib\nvfprintf.c): the `break 0,7` that kept them in intentional_asm is gcc's own\ndivide-by-zero check. JumpToRfuDispatch, JumpToRfuStatus, RfuDispatchEntry and\nUpdateRfuDispatchState: tail calls the SDK compiler emits itself. All six are\nbyte-exact on the SDK compiler with no flags and no asm, and leave\nintentional_asm.\n\n* chore: regenerate progress report\n\n* config: eight units built on privileged COP0 instructions are intentional asm\n\nsynchronize_cache_range, enable_intc, disable_intc, enable_dmac, disable_dmac,\nhandle_end_image, DIntr and EnableInterrupts reach their retail bytes only\nthrough inline asm, because the bytes hold mfc0 Status, ei/di or sync. No C\nsource can produce those, which is the policy's no-C-equivalent bar, so they\nleave the C goal instead of sitting in it as pending units. A scan of all 210\npending units' objects found no other unit that clears the bar (domc's mult1\nis emitted by the SDK compiler itself).\n\nC_EXACT 41.59 % -> 41.67 % (denominator 346 492 -> 345 780 B).\n\n* decomp: four units ported from the PAL decompilation (rac1-decomp)\n\nfun_001ec8a0 and fun_001edaa8 (camera.c), fun_00221b50 (pause.c) and\nfun_0022df40 (space.c), from rac1-decomp at f564648 by pal-wave: whole-file\ncontext, names aligned to our listing, minimized. Byte-exact on the game\ncompiler with no flags; two use the approved qcopy() macro and nothing else.\n\n* chore: regenerate progress report\n\n* fix: compiler patch 0056 emits an sda variable's .extern before its first use\n\nSN's Ps2EeAs is single-pass: it addresses a symbol gp-relative only when the\nsymbol's size is known before the reference. cc1 printed every .extern in the\nend-of-file list, too late, so the only way to reproduce retail's gp-relative\naccesses was an inline `__asm__(\".extern NAME, SIZE\")` in the unit. With the\npatch, a variable declared `__attribute__((sda))` (SN's attribute, ported in\n0044/0045) gets its .extern at its first use, ahead of the function's text.\nUnmarked externals keep the end-of-file placement, where retail keeps them\nabsolute, so the patch is inert without the attribute: the stack through 0056\nrebuilt from the archive, the installed cc1 replaced, full-ELF gate PASS.\n\n* decomp: sda attribute instead of inline .extern asm; two units unblocked\n\nThirteen promoted units drop their `__asm__(\".extern ...\")` lines: eight\ndeclare the variable `__attribute__((sda))`, and in three the directive's size\n(12) only kept the variable absolute, which a plain extern already does. Two\npending units that needed the same directive, fun_00206b78 and fun_0022e8c8,\nare now byte-exact C with the attribute and are promoted. fun_0021b6d8 keeps\nits directive: with the attribute cc1 costs the address differently and the\nregister allocation moves. Full-ELF gate PASS.\n\n* chore: regenerate progress report\n\n* decomp: fun_0021c4c0 exact; 19 promoted units drop their inline asm\n\nfun_0021c4c0 reads the menu owner before the level load. Nineteen promoted files reach retail as plain C on the current compiler: register pins and barriers removed, with callees declared void where their result is unused, arg0 of PackDmaTag an int, and two permuter-found spellings. Every file carries a linked-byte proof; full-ELF gate PASS.\n\n* chore: regenerate progress report\n\n* config: add D_0018E340, the light array base (0x18E340) that fun_001f4880 indexes; gate PASS e0505810\n\n* decomp: 6 exact units ported from the PAL decomp; gate PASS e0505810\n\nupdate_world_object_animation, setup_menu_display_text, transition_update_movie_camera, build_object_rotation_matrix, fun_001f4880, fun_001ed2b0.\n\n* chore: progress report 45.72 % C_EXACT\n\n* decomp: update_all_point_lights, fun_002269c0 exact (PAL ports); gate PASS e0505810\n\n* decomp: 8 promoted units drop register pins and barriers (not needed); gate PASS e0505810\n\n* decomp: 3 promoted units drop inline asm (void callee, symbol address instead of a pinned constant); gate PASS\n\n* docs: scope is the boot ELF; level overlays reported as 0 %\n\nprogress/report.json gains an empty overlays category (outside the totals); progress-metrics and engine-source-layout say what the level code overlays are. The progress map is titled as the boot ELF (SCUS_971.99).\n\n* docs: shorter progress map title\n\n* decomp: sceSifRemoveCmdHandler drops its register pins (the parameter holds the buffer); gate PASS\n\n* decomp: sceSifAddCmdHandler drops its register pins (the parameter holds the buffer); gate PASS\n\n* decomp: fun_0021b6d8 sda instead of .extern; drop a stray .align; libgcc multiply units are intentional asm; gate PASS\n\n__divdi3, moddi3, __muldi3, udivdi3, umoddi3 are libgcc2.c built with gcc's longlong.h, whose umul_ppmm is inline asm (multu into lo/hi) in the original source.\n\n* decomp: compute_cross_product_sign drops its pins and barriers (the product is its own block); gate PASS\n\n* decomp: fun_001f4d98 exact (PAL port; the packet cursor is a struct field, reloaded after every store); gate PASS\n\n* decomp: set_state_field, cdvd_exit drop pins and barriers (a do/while block keeps the store in place); gate PASS\n\n* chore: shared sda.h for NOT_SDA/MACRO_ADDR; PAL ports trimmed to what their function uses\n\n81 files drop their local NOT_SDA/MACRO_ADDR defines for include/sda.h. The nine PAL ports no longer carry the whole PAL source file (its inlined common.h/structs.h and other functions' declarations): about 8,800 lines become about 590, each object compared instruction for instruction and the full-ELF gate passing. Identifiers bound to NTSC symbols by asm labels now carry the NTSC name.\n\n* chore: src/textbin moves into subsystem folders; 86 functions get evidence-backed names\n\nAll 351 promoted units under src/textbin/ now live under src/<subsystem>/ (rule 7 of docs/decompilation-tips.md). The folder follows the original source file rac1-decomp (PAL) places each function in (camera.c, draw.c, help.c, hud.c, map.c, menu.c, pause.c, missionfunc.c, ...). 86 of the 272 unnamed functions get a lower_snake_case name bound to their FUN_ label; the others keep their address name until their role is settled. config/us/recovered_names.json records each group and name with its evidence. materialize-textbin-oracles.py also serves promoted units still named after their address. Full-ELF gate PASS e0505810; C_EXACT unchanged.","measures":{"fuzzy_match_percent":79.474014,"total_code":339440,"matched_code":160852,"matched_code_percent":47.387463,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1164,"matched_functions":918,"matched_functions_percent":78.86598,"complete_code":160852,"complete_code_percent":47.387463,"complete_data":0,"complete_data_percent":0,"total_units":116,"complete_units":66}},{"timestamp":"2026-09-27T14:28:10Z","commit_sha":"56be84d60335d1be21c1df4b52ff95e6eabd43f9","commit_message":"decomp: import 112 units from the PAL decompilation (rac1-decomp), cc1 0055, qcopy macro (#15)\n\n* decomp: import 10 exact units from the PAL decompilation\n\nrac1-decomp (Lynder063/rac1-decomp, the SCES-50916 decompilation) has C for\n56 of our pending units. Ported through the cross-region correspondence with\nthe whole foreign file as context, symbols renamed from our retail listing,\nreduced to what each function needs and re-proved on the game compiler:\n\n  fun_001ee008, fun_001f4be0, fun_002050e8, fun_00221f58, fun_0022c658,\n  fun_00239d60, send_adpcm, music_start_track_body, music_update_stream,\n  draw_ties_2\n\nEach file names its foreign source. No inline asm: the foreign 16-byte\nqcopy became a TImode copy (lq/sq from plain C). Full-ELF gate PASS;\nprogress 44.70% -> 46.01%.\n\n* docs: credit rac1-decomp for the ported PAL functions\n\nThe README credits and the third-party notices now say that part of the C\nis the PAL project's decompilation, how a ported file is marked, and that\nthe ported code stays its authors' work.\n\n* docs: shorten the rac1-decomp credit\n\n* decomp: 9 more PAL imports, cc1 0055 keeps the second HI/LO pair fixed\n\n- camera_activation_check_priority and fun_00222768 carry their switch\n  tables; RODATA_OVERLAYS places them at the retail address\n- init_ref_images (SDK), setup_gif_paging, build_image_transfer_tag,\n  fun_001e9488, memcard_save_data, memcard_restore_info, fun_001fe980:\n  NTSC names from the retail listing, and the 8-byte shorter memory-card\n  slot struct of the NTSC build\n- patch 0055: the retail game code never multiplies on pipeline 1\n  (436 mult, no mult1), so the game compiler no longer allocates the\n  second HI/LO pair; all 494 byte-identical game units stay identical\n\nFull-ELF gate PASS.\n\n* decomp: split 76 PAL-identified functions out of text gaps, 71 as C\n\nThe correspondence placed 76 PAL C functions inside our text gaps with\nidentity 1.0; each ends in jr $ra + delay slot at the placed size. The\ngaps are cut there (yaml, pending wrappers, function map) and 71 of the\nnew units are the PAL C, proven byte-exact; 5 stay pending.\n\nSources that took one of these addresses as a splat data name (callbacks\nsuch as D_0012F1C8) now call the function by name, and the oracle\nmaterializer also collects alias spellings from the expected listings.\n\nFull-ELF gate PASS.\n\n* config: place fun_001fdc08's switch table at its retail address\n\n* config: name fun_001fe980's overlay a switch table\n\n* decomp: 22 more PAL imports, the original qcopy macro, 8 more gap functions\n\n- include/qcopy.h: the original's inline-asm 16-byte copy (lq/sq through\n  $2, addresses in registers). All 154 such copies in the retail game code\n  have that shape, which no C copy reproduces; used only where a plain\n  TImode copy cannot. 15 units build with it.\n- 8 functions cut out of text gaps: placements re-anchored to the retail\n  function start, and boundaries taken from our retail where the foreign\n  C compiles to another length; 7 are PAL C.\n- callees spelled the way the link binds them (FUN_00214530, FUN_0020cb10)\n\nFull-ELF gate PASS.","measures":{"fuzzy_match_percent":78.932365,"total_code":345616,"matched_code":169724,"matched_code_percent":49.10768,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1168,"matched_functions":954,"matched_functions_percent":81.678085,"complete_code":169724,"complete_code_percent":49.10768,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":60}},{"timestamp":"2026-09-27T12:30:57Z","commit_sha":"36f72ae7478f1524f32c6964b022f1815b3cdbb4","commit_message":"config: two compilers routed by provenance, game code assembled by Ps2EeAs, units own their small data (#14)\n\n* config: remove 64 measured-redundant per-unit overrides\n\nThree batches, each accepted only after verify-baseline.sh passed with the\nsame linked ELF hash (e0505810...) as before the change:\n\n  batch 1  9 flag entries deleted, 3 reduced\n  batch 2  45 of 47 PADLESS_POLICY_UNITS entries deleted\n  batch 3  10 entries whose owners are still pending INCLUDE_ASM wrappers\n\nAn entry counts as redundant only when the production build produces the\nsame allocated sections and relocations without it. The probe that measures\nthis lives in the tools repo (scripts/flag-removal-probe.py).\n\nKept, with reasons:\n  at-store on sdk/library/picturecodingextension (removal breaks the build)\n  la-gprel on fun_0022f778 (owner still pending; kept as the record for\n    promotion)\n  the four -ffixed-N register pins on textbin/fun_0021b6d8 (a subset probe\n    was wrong and the gate caught it: 4 bytes differed inside that unit)\n  the 17 SN entries bypassed because their owners build on cc_game\n\nDeclared entries 124 -> 60 (compiler flags 77 -> 58, policies 47 -> 2).\n41 live overrides remain and all 41 still change bytes. The migration plan,\nthe evidence and the next step (-mno-split-addresses as a default change)\nare in docs/COMPILER_FLAGS_POLICY.md in the tools repo.\n\n* config: require the reconstructed game compiler, delete 17 dead SN entries\n\nconfigure.py used to omit the cc_game rule when the compiler was missing and\ncarry on, which silently routed all 297 game units to a different compiler -\nthe repository ignores tools/, so a fresh clone did it unnoticed. It now stops\nwith a message that says where the compiler is expected.\n\nThat closes the only configuration in which the 17 bypassed SN_FLAG_UNITS\nentries could ever be read, so they are deleted. Each was measured first by\nappending its declared flags to the unit's current route flags: all 17 change\nnothing on the route in use. fun_00207300 was checked on its own, because its\nflags sat in the table cc_game never reads and looked like a missing entry;\nmeasured, they change nothing there either, so nothing was added.\n\nDeclared entries 124 -> 43 (compiler flags 41, assembler policies 2). Gate:\nPASS, linked ELF hash unchanged at\ne050581032e4bb3f20341307da5b69b76f1574910519155380ea771e55c3c0c9.\n\nAccepted cost: a public clone cannot build without a local game compiler.\nscripts/setup-linux-cloud.sh in the tools repository builds one.\n\n* docs: state the current build requirements, drop campaign notes\n\nThe game compiler is required, so say so where a builder looks first: the\nfront page, the build guide and tools/README. It is rebuilt from the patch\nstack in patches/, which records the pinned archive, its SHA-256 and the\nhost recipe, so the requirement is satisfiable from public sources alone.\n\nThe flag tables carried notes from the removal work: batch numbers, dates,\nlinks to documents in the other repository. Those are gone; what remains\nsays what each surviving option does and what has to be measured before one\nis added or removed again.\n\ndocs/decompilation-tips.md described adding per-owner options as a normal\nstep. It now says what it is: a last resort, with a measured cause, and a\nreason recorded next to the entry.\n\nGate: PASS, linked ELF hash unchanged.\n\n* config: move 71 units off the SN route onto the game compiler\n\nEach unit was rebuilt with the other compiler and compared against the\nproduction object: 71 of the 113 SN-routed units produce identical allocated\nsections and relocations on the reconstructed game compiler, so their route\nentry moves and their comment moves with it. 2 flag entries travel with their\nunits, because the game compiler needs the same option there.\n\nThe vendored EE-GCC 2.9 route is not an alternative: only 3 of the 113 units\nare identical on it, since it saves sd/ld where this code saves sq/lq.\n\nSN now builds 42 units instead of 113. Gate: PASS, linked ELF hash unchanged\nat e050581032e4bb3f20341307da5b69b76f1574910519155380ea771e55c3c0c9.\n\nThe remaining 42 differ in .text and need source or compiler work before the\nroute can go; they are listed with their deltas in the tools repository.\n\n* config: build debug_print with the game compiler\n\nThe unit needs a stdarg.h, and only the SN tree shipped one. The reconstructed\ncompiler's own gcc/ginclude has all three headers it wants - stdarg.h,\nstddef.h and va-mips.h, identical to the SN copies - they were simply never\ninstalled, because the driver was configured with a prefix that no longer\nexists and so searches no include directory at all.\n\nThey now live in tools/compilers/game-compiler/include, the cc_game rule adds\nthat directory with -I, and the unit moves to the game compiler. Its\nprologue was always a plain argument-window save: the va_start is dead code,\nso the retail bytes never depended on the SN headers' layout.\n\nGate: PASS, linked ELF hash unchanged. SN edges 42 -> 41.\n\n* config: teach the assembler the retail 64-bit immediate form, move 5 units\n\ncc1 folds a 64-bit constant into one dli pseudo-instruction, and the two\nassemblers expand it differently. The original one shifts a 16-bit field into\nplace and adds the low 16 bits; the reconstructed gas could only find a shifted\n16-bit constant when one 32-bit half of the value was entirely zero, so for a\nvalue with a top and a bottom 16-bit field - the GS and ADX mask constants are\nall of that shape - it fell back to a lui/dsll32/ori sequence with different\nbytes. The new patch recognises the retail form when the middle 32 bits are\nzero, which is narrow enough that no existing expansion changes.\n\nGas is the assembler for every game-compiler edge, so this was checked with the\nfull gate rather than a sweep: PASS, linked ELF hash unchanged, before and\nafter. Five units that were only reachable through the SN assembler because of\nthis macro are byte-identical on the game compiler now and move over. SN edges\n41 -> 36.\n\nPatch 0050 is added to the stack with its SHA-256, so the compiler stays\nreproducible from this directory.\n\n* config: keep the bank symbol absolute, move its unit to the game compiler\n\nsnd_bank_load_from_ee_cb passes &D_0015ED00 to sceSifCallRpc, and a scalar\nextern of that symbol makes cc1 emit la, which the one-pass r5900 assembler\nthen resolves gp-relative. Retail has an explicit lui/addiu pair there, so the\nsymbol must stay out of small data at that site. Declaring its size in the\nfile-scope extern block is what the project's own lessons describe for this\ndecision (extern-size-decides-split-vs-gp), and it makes the store and the\nargument pair match retail.\n\nMeasured 100.0/100.0/100.0 exact on the game compiler with a linked-byte proof,\nand unchanged on its registered padless route. Gate: PASS, linked ELF hash\nunchanged. SN edges 36 -> 35.\n\n* config: stop the assembler inventing a hazard nop after a coprocessor move\n\ninsn_uses_reg() masks floating-point register numbers with &~1, because the\nassembler cannot tell \"reads both $f0 and $f1\" from \"reads one of them\". That\npairing is right for the load/store case it was written for and wrong for a\ncoprocessor move: mtc1 into $f4 does not touch $f5, so the delay-slot search\ncounted a hazard and inserted a nop the original assembler never emitted. That\nsingle nop was the whole residual for two units, and no source shape removes\nit - the retail stream pins the mtc1 directly before the multiply.\n\nPatch 0051 uses a variant of the predicate without the pairing, in the\ncoprocessor-move branch only. Gas assembles every game-compiler edge, so the\ncheck was the full gate: PASS, linked ELF hash unchanged. textbin/fun_001f2070\nand init_view_context are byte-identical on the game compiler and move over.\n\nSN edges 35 -> 32.\n\n* config: give the assembler the full retail dli and la rules, move 10 units\n\nTwo assembler differences kept SN-routed units off the game compiler.\n\ncc1 folds a 64-bit constant into one dli, and 0050 only reproduced the retail\nexpansion when the middle 32 bits were zero. Every multi-instruction 64-bit\nconstant in the game's expected listings follows one rule: 16-bit fields built\ntop-down, the first aligned to the highest set bit and each next one to the\nhighest bit still missing, with the shifts between them merged. Patch 0052\nreplaces the narrow rule with that one; a plain 2^n - 1 mask and values with an\nall-ones high word keep the forms the listings show for them.\n\n0020 gave loads and stores the retail rule for a symbol whose size is not yet\nknown at the use (absolute lui/<op> in reorder mode), but the la macro kept the\nrelaxable gp pair, so an 8-byte symbol retail addresses as lui/addiu came out\ngp-relative. Patch 0053 applies the same predicate to la.\n\nThe published stack rebuilds the installed as byte for byte. Gate after each\npatch: PASS, linked ELF hash unchanged. Ten SN units are now byte-identical on\nthe game compiler and move over. SN edges 32 -> 22.\n\n* fix: drop the fun_001ffe18 alias that broke objdiff symbol pairing\n\nThe alias gave the object two symbols at one address. The one caller that used the alias name now binds to FUN_001ffe18 through an asm label, the idiom the other callers already use. Gate PASS, linked ELF hash unchanged.\n\n* decomp: promote 9 byte-exact units on the converged compilers\n\nEach reaches code/function/data 100.0 with zero differing rows and the\nlinked-byte proof against retail, so its pending wrapper retires and the C body\nbecomes the unit. None of them needs a per-unit flag or assembler policy.\n\n  game compiler\n    textbin/fun_001fb8f0                    flat-shaded sprite rectangle\n    textbin/fun_00220e28                    options list menu\n    textbin/fun_00220850                    HUD pickup icon\n    textbin/fun_00223e28                    flashing highlight box\n    textbin/audio/music/process_bgm_display_text_event   scaled font print\n    textbin/ui/text/font_print              integer font print\n    textbin/ui/menus/missions/draw_missions_menu\n    textbin/fun_00239160                    shop footer\n  SDK compiler (libcdvd, same provenance as fun_00120a28)\n    textbin/fun_00120d40                    cd command guard\n\nGate PASS, linked ELF hash unchanged. Progress 43.23 % matched.\n\n* docs: drop the compiler note from the README warning\n\n* config: name the two compilers game-compiler and sdk-compiler\n\nThe vendored EE-GCC 2.9-991111-01 tree becomes tools/compilers/sdk-compiler\nand the build rules become game-compiler and sdk-compiler (were cc_game and\ncc); its per-unit flag table is SDK_COMPILER_FLAG_UNITS. The gate checks for\nboth compilers. No object changes: gate PASS, linked ELF unchanged.\n\n* config: route every unit by provenance, list the rest as ROUTE_EXCEPTIONS\n\nThe retail executable links the SDK libraries as one block ahead of the game\ncode, and each block was built by its own compiler. configure.py now gives a C\nunit the compiler of the block it sits in: sdk-compiler below GAME_TEXT_START\n(0x12D8F8), game-compiler from there on. That replaces the per-unit route sets\n(GAME_COMPILER_UNITS, SDK_COMPILER_UNITS, SN_COMPILER_UNITS,\nTEXTBIN_ORIGIN_UNITS, PADLESS_ASM_UNITS, EE_GCC_PATCHED_UNITS) and the sq/sd\nsave-style fingerprint.\n\nMeasured on a clean gate workspace with the common configuration (no per-unit\nflags), 1258 of 1331 C units build byte-identically on their provenance\ncompiler. 421 of them move there now (408 from the SDK compiler, 11 from the\npatched 991111 route to the game compiler, 1 to the SDK compiler, and\nappend_dma_tag, whose -G0 -mno-split-addresses was only needed on the SDK\ncompiler). The 42 that do not reproduce yet keep their route in\nROUTE_EXCEPTIONS: 22 SN, 8 patched 991111, 12 game functions on the SDK\ncompiler. The table only shrinks; a unit that needs SN now fails configure\ninstead of silently falling back to another compiler.\n\nThe flag tables are keyed by exact unit name instead of suffix, and the dead\nfun_0022f778 padless policy (its unit is a pending wrapper) is gone.\n\nGate PASS, linked ELF unchanged.\n\n* fix: reduce provenance route exceptions\n\n* decomp: promote 15 byte-exact units recovered from the retail listing\n\nFifteen pending units are now byte-exact with a linked-byte proof: 100/100/100\nin objdiff and retail_verification.exact on the unit's own route. Each was\nremeasured after promotion, not trusted from the promotion run.\n\nThe work started from the question of how much of a second build of the same\nprogram could be carried across, and the answer for this batch is that the\nexpensive part of a unit is working out what its code means. Once that is known,\nthe remaining percent is register allocation, and the levers below are what\nclosed these bodies.\n\n  - the candidate must define the sized symbol of the retail oracle and carry\n    no __asm__ label: a label renames the function and objdiff then reports an\n    unpaired function instead of a percentage\n  - a callee's return type comes from its own disassembly (abs.s is f32,\n    trunc.w.s; mfc1 is s32, a VU vadd.xyz is void); an unprototyped callee\n    silently promotes f32 to double and emits jal fptodp\n  - __asm__(\".extern D_x, 4\"); flips a load into retail's gp form, and the\n    directive belongs at the end of the file: cc1 already emits it there and the\n    assembler is single-pass, so a top-of-file directive relaxes every access\n    instead of only the delay-slot store\n  - array-vs-scalar spelling of a global is a coin flip worth 3-5 rows; the\n    scalar form gives retail's adjacent lui + lw %lo(reg)(reg) where an array\n    extern makes cc1 hoist the lui\n  - a global packet pointer has to be wrapped in a struct so it is reloaded\n    after each store, which is what do_gif_paging needs\n  - indexing a struct pointer at every use, instead of hoisting a local,\n    reproduces retail's six reloads in vi_buf_get_ts\n\nA data global is addressed by the name our retail listing gives it, not by an\noffset: the two builds lay their data sections out differently and the deltas\nare not constant, but the order in which retail touches its globals is.\n\nlink_localized_display_text calls func_0022DB10, a function still kept in raw\ntextbin, so it is now declared in undefined_funcs_auto.txt next to the other\n82 references of that kind. fun_0021d338 calls the audio stream starter by its\npromoted name, as its siblings do.\n\n* config: keep five promoted units on the SN line\n\nClosing the route exceptions moved every game-code unit onto the game compiler,\nincluding five that had been promoted while the SN line was still legal for\nthem. Their bodies are byte-exact there and 89.8-99.5% on the game compiler,\nand four of them come out 4-8 bytes short in .text - which shifts every later\naddress and turns the full-ELF gate red in scattered fragments, long after the\nper-unit numbers have gone quiet.\n\nA per-unit score cannot see this. It is measured on the registered route, while\nthe build uses the provenance route, and the two drifted apart when the policy\nchanged. Only the gate compares the whole image, so any future move of a route\nhas to be treated as changing the compiler under every unit that used it.\n\nThese five are listed as measurements, not preferences, and each is a candidate\nfor retirement: the residual is small and the levers are known.\n\n* docs: credit the PAL toolchain notes, and describe only the current setup\n\nThe toolchain notes on GCC 2.95 sub-build differences, register-spill widths and\nsmall-data addressing were useful reference for this project's compiler setup,\nand are credited as such.\n\nThe rest is the documentation catching up with itself. Four files described a\nstate the repository had moved past, and each described it in a way that would\nhave been wrong to copy:\n\n  - building.md justified the game compiler by contrast, \"not optional\", and\n    tagged two toolchains \"(retiring)\". Both phrasings only make sense against a\n    previous configuration, so a reader had to infer one. The requirement is now\n    stated as a requirement, and the tables list what the variables do.\n  - patched-toolchain.md carried \"(optional)\" in its title for the same reason.\n    The fact that make elf works without the profile is real and stays, but as a\n    statement about the build rather than about the toolchain's status.\n  - recovered-names.md quoted 689/395/292/2 entry counts. They were already\n    wrong - the file holds 402 proposed and 285 unresolved - and the summary\n    object it pointed at for the authoritative numbers is empty. It now points\n    at the fields that are regenerated with the catalog.\n  - commit-messages.md used two real past metrics, C_EXACT 485 / 65,428 B and an\n    audit of 465 units, as format examples. The convention is still shown; the\n    figures are not a format.\n\n* config: six more units the game compiler does not reproduce\n\nSame cause as the five listed before, found by looking in the right place. That\nlist came from comparing compiled .text sizes, which can only see a unit whose\nsize moved. These six come out the right size with the wrong bytes, so a size\ncomparison calls them identical and they were never candidates. They surfaced\nin the full-ELF diff instead, one to two fragments each.\n\nMeasured per unit, game-compiler -> padless:\n\n  fun_001fb8f0  98.93 -> 100.0      fun_00223e28  98.56 -> 100.0\n  fun_001ffe18  99.56 -> 100.0      fun_0022ea08  97.00 -> 100.0\n  fun_00200600  99.69 -> 100.0      fun_00239690  97.45 -> 100.0\n\nWorth stating plainly, because it is the kind of check that looks conclusive and\nis not: a size comparison is not a correctness check. It answers \"did the\ncompiler lay this out differently\", which is one way to be wrong and not the\nonly one.\n\n* fix: make the gate green again\n\ninitialize_global_state_entry is the three stores retail makes; what went\nwrong was their order and addressing. Retail stores D_0015F618 second and\nD_0015F5B0 last, in the jr delay slot, and addresses the two first globals\nthrough the assembler macro. Scalar declarations give the macro form, and\nwriting the two flags as one chained assignment gives retail's order on the\ngame compiler with the common configuration. The .sdata section attributes\nadded in 0626871 are gone; they only moved which store landed in the slot.\n\nfun_00214a98 and set_tfrag_dists call truncate_float_to_s32 through the\nfunc_001FA6D0 alias, which no source defines. It resolved only when that unit\nwas built from the retail oracle, whose object carries both labels; built from\nC it failed to link. The declarations now bind the name to FUN_001fa6d0.\n\ndraw_fogged_fullscreen_sprite needs no change: it is byte-identical on the game\ncompiler whose assembler carries patches 0052 and 0053.\n\n* config: assemble the game code with Ps2EeAs, 18 route exceptions close\n\nRetail was assembled by SN's Ps2EeAs, and a large part of what the game\ncompiler had to imitate is that assembler: it pads short loops and div\ninstructions itself, needs a symbol's size before a use, and has its own dli\nand la forms. The game-compiler rule now runs the game compiler's cc1 (-S)\nand hands its output to Ps2EeAs through the existing padless helper. The\npending INCLUDE_ASM wrappers stay on the game compiler's GNU as.\n\n- cc1 patch 0054: cc1 stops imitating the assembler's loop padding (the Cygnus\n  lengthen pass and the post-dbr pass of 0019/0046), and the 0025 dead-slot\n  annulment is opt-in again. Measured with Ps2EeAs over the game range with the\n  common configuration: 478 of 522 C units byte-identical.\n- No -g for the game code: its line-number labels are \"possible branch\n  destinations\" to Ps2EeAs, which then pads a nearby div.s that retail does\n  not pad.\n- The helper's finish step trims data sections Ps2EeAs rounds up to their\n  alignment back to the size the game compiler's GNU as gives the same source\n  (a jump table in .rodata came out 36 -> 48 bytes).\n\nUnits that close on this route with no source change: snd_bank_load_by_loc,\nfun_00226670, vi_buf_stop_dma, find_valid_animation_frame_index,\nvideo_dec_flush and the eleven dli/la units that 6a120e8 and 10ea7b7 had moved\nback to SN (their failure was an assembler without 0052/0053; with Ps2EeAs\nthere is nothing to patch). Two close with plain C: fun_002133d0 is the cosine\ninterpolation written as three returns, calculate_ring_buffer_bounds takes its\nerror path as an early return.\n\nROUTE_EXCEPTIONS 46 -> 28. Gate PASS, linked ELF unchanged.\n\n* config: build Insomniac's hand-written fast_* math units as intentional assembly\n\nmultiply_global_factor_ed64/ed70, multiply_global_scale,\nconvert_integer_to_float and truncate_float_to_s32 belong to the\nhand-written fast_* module (addi, $at/$f14/$f15 scratch, no mtc1 hazard\nnops). They move to src/assembly as INCLUDE_ASM units in the\nintentional_asm category and leave ROUTE_EXCEPTIONS and the patched flag\ntable (23 exceptions left).\n\nThe expected-asm normalization now also rewrites gp-relative lwc1/ldc1,\nand wrappers that include a FUN_*.s oracle get it materialized.\n\n* decomp: units own their small-data variables, 5 route exceptions close\n\nPs2EeAs reaches a variable gp-relative only when it knows its size before\nthe use: in a delay slot, or after its definition in the same translation\nunit. Units that retail reaches gp-relative now define those variables\nahead of their functions, and the new SDATA_OVERLAYS table places each\nunit's .sdata at its retail address inside the preserved small-data\nblobs (like RODATA_OVERLAYS).\n\n- update_resource_counter defines D_0015F8F8.\n- fun_001f0bd0 defines the debug-text cursor D_0015F000/F004.\n- snd_got_returns and StoreObjectIndex share D_0015EC80/84 and merge into\n  audio/rpc/snd_returns.c.\n- vu1_send_chain and vu1_sync_chain share D_00160EE0 and merge into\n  rendering/vu1_chain.c (its .extern lines go too).\n\nAll five build on the game compiler; ROUTE_EXCEPTIONS drops to 18.\n\nTooling: the preserved core_lit/lit blobs no longer export labels; the\noracle materializer handles multi-function units and labels functions\nwith their symbol_addrs names; the rename catalog allows one row per\nfunction of a unit. Progress report and decomp map regenerated.","measures":{"fuzzy_match_percent":76.95834,"total_code":340564,"matched_code":152232,"matched_code_percent":44.699966,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1084,"matched_functions":842,"matched_functions_percent":77.67528,"complete_code":152232,"complete_code_percent":44.699966,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":60}},{"timestamp":"2026-09-26T20:53:56Z","commit_sha":"f1545956732792026877da80a390361a891666f9","commit_message":"decomp: 8 exact promotions, 20 staged bodies, 41.71% matched\n\n* decomp: promote 8 byte-exact units\n\nEach reaches code/function/data 100.0 with zero differing rows and the\nlinked-byte proof against retail, so its pending wrapper retires and the C\nbody becomes the unit.\n\n  native (game compiler)\n    textbin/audio/music/music_start_track_50000\n    textbin/rendering/sky/do_sky_gif_paging\n    textbin/fun_00207e58\n  padless, no policy rewrite\n    textbin/fun_00200600\n    textbin/fun_0021b6d8\n  padless, la-gprel\n    textbin/fun_00212ed8\n    textbin/fun_00221460\n    textbin/rendering/texture/parse_particle_textures\n\nThree of these were recorded as walls that no source shape could move. The\nlisting's `dsll32 rd, rt, N` is a shift by N+32 on the R5900 and the\ndisassembler prints the encoded `sa`, so the packet constants have to be\ndecoded from the raw oracle words; declaring a paging flag as an array extern\nroutes its address through a register, which lets the lui stand alone at the\ntop of the body; and a swapped pair of induction pointers is the ORDER of the\ntwo increments in the for-increment clause, not the loop shape.\n\nfun_0021b6d8 is the one exact that needs per-unit flags. The recreated\n`local_alloc` ranks argument registers above v0/v1 for short-lived pseudos, so\nthe two `!= -1` condition pseudos land in a3 and v1 where retail uses v1 and v0.\nThe entry goes to SN_FLAG_UNITS, and the full-ELF gate is what proves it takes\neffect: the built SHA-256 is unchanged at e0505810...c3c0c9.\n\n* decomp: stage 20 banked near misses\n\nAlso removes two wrong public bodies. font_print's bank held a deleted\n`best.CONTAMINATED.c` defining a different function (getEffTypeString), and\nselect_world_object_resource_tables was marked contaminated with a switch over\nsymbols that appear nowhere in the retail listing. Both are now real C.\n\nfun_00207e58's bank counted 0x40 where retail counts 0xF, writing 256 bytes\ninto the 64-byte buffer that func_001F98D0(dest, buf, 0x40) consumes. objdiff\ncould not see it: the instruction stream is identical and only the counter\nimmediate differs.\n\nFull-ELF gate: PASS, built SHA-256 e0505810...c3c0c9.\nProgress: 40.01% -> 41.71% matched, 67.75% fuzzy, 60/109 groups, 825/1331 units.","measures":{"fuzzy_match_percent":67.74967,"total_code":340608,"matched_code":142052,"matched_code_percent":41.70542,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1090,"matched_functions":825,"matched_functions_percent":75.68807,"complete_code":142052,"complete_code_percent":41.70542,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":60}},{"timestamp":"2026-09-26T18:02:13Z","commit_sha":"8f492e552514e7ae00c41198bce15a2dac92c9f4","commit_message":"decomp: 8 exact promotions, 10 staged bodies, README headings (#13)\n\n* decomp: return fun_001f2070 to pending until the SN assembler matches it\n\nThe unit was promoted on the sn route, but the linked build is not byte-exact\nhere: the SN assembler keeps one hazard NOP after `mtc1 at, ft2` that retail\ndoes not have. The object grows from 0x134 to 0x138, every later text section\nshifts by 4, and verify-baseline.sh fails with a 259,560-byte difference.\n\nNo route or flag set closes it: sn and native both measure 98.70 with the one\ninserted NOP, padless 97.40, patched 92.62, and -g0 / -G0 / -G8 /\n-mno-check-zero-division change nothing. It is the same toolchain gap as\ninit_view_context and fun_00214a98.\n\nThe pending wrapper, its NON_MATCHING body and the linker-config entry come back\nfrom before the promotion, and the unit leaves SN_COMPILER_UNITS. The C body is\nkept in the candidate bank at 98.70 on sn.\n\n* decomp: promote 7 byte-exact textbin and runtime units\n\nSeven units reach code/function/data 100.0 with zero differing rows and the\nlinked-byte proof against retail, so their pending wrappers retire and the C\nbody becomes the unit.\n\n  native (game compiler)\n    fun_00203120                  upload texture/CLUT images to VRAM from the\n                                  D_0015EE8C page cursor\n    obtain_all_gold_weapons_menu  the two-line \"all gold weapons\" message box\n    fun_00206860                  decode one row of 4bpp run-length pixels\n  sn\n    fun_00208030                  4bpp coverage map -> 1bpp threshold mask\n  padless (policy none)\n    fun_001ffc30                  textured sprite GIF packet\n    fun_001ffe18                  textured quad as a triangle-strip GIF packet\n  sony-2.9\n    convert_multibyte_character   newlib _mbtowc_r for the C locale\n\nThe levers that closed them:\n\n  * the x argument of sceGsSetDefLoadImage is an int computed as\n    (vram << 8) >> 16, not an s16 cast (fun_00203120)\n  * one int local reused for both unkA stores keeps the value in s1 across\n    the call (obtain_all_gold_weapons_menu)\n  * a separate loop variable per loop, and the source pointer declared as an\n    unsized array so it is not gp-relative (fun_00208030)\n  * a local copy of the output pointer, and the end offset indexed by row\n    after the branch rather than inside it (fun_00206860)\n  * newlib's own statement order: `s != NULL && n == 0` is tested before\n    `s == NULL` (convert_multibyte_character)\n  * the tag idiom `tag = p; q = tag + 1; p = tag + 1;` with the fixed-point\n    corners written inline (fun_001ffc30, fun_001ffe18)\n\n* decomp: stage 10 recovered bodies and two flag entries for the public score\n\nTen pending units get a new NON_MATCHING body, each kept only because the public\nharness (check-unit.py) measures it higher than the body it replaces:\n\n  fun_00206bd8                   0.00 -> 88.29\n  sceRead                        0.00 -> 96.25\n  scewrite                      85.10 -> 94.57\n  fun_002271d0                  35.51 -> 48.71\n  fun_0021a1e0                  84.05 -> 84.85\n  snd_flush_sound_commands, link_localized_display_text,\n  memcard_restore_data, sky_draw_shell_textured and init_mem_slots,\n  whose previous bodies were placeholders or code from another game\n\nThe matching build is unchanged: every unit still assembles from its oracle.\n\nGAME_COMPILER_FLAG_UNITS gains the banked flag sets of fun_001f33b8\n(-fno-schedule-insns) and fun_00221f58 (-G0), so the public harness compiles\ntheir bodies the way the bank measured them.\n\n* chore: refresh the progress report and the map for the batch\n\n  matched code       136,288 -> 138,788 of 340,608 B   40.01 -> 40.75 %\n  matched functions  810 -> 816 of 1,090                74.31 -> 74.86 %\n  fuzzy match        69.60 -> 70.78 %\n\nSeven promotions, one unit returned to pending (fun_001f2070), and ten staged\nbodies. Nothing is degraded.\n\npython3 scripts/gen_progress_report.py --check: progress/report.json is current.\npython3 scripts/test_public_tools.py: 73 tests OK.\n./verify-baseline.sh: PASS (e050581032e4bb3f20341307da5b69b76f1574910519155380ea771e55c3c0c9).\n\n* docs: use h3 section titles in the README\n\n* decomp: promote fun_001f2070 on sn with -Wa,-mips4\n\nThe body was byte-exact except for one NOP the SN assembler adds before\n`mul.s $f1,$f1,$f5`. cc1 emits `li.s $f5` and `li.s $f4` back to back in\nreorder mode, and gas, in its default ISA, treats the write to $f4 as a hazard\nfor the read of $f5 (the even/odd register pair) and pads it. Retail has no\nNOP there. Assembling in MIPS IV mode (-Wa,-mips4), where coprocessor moves\ninterlock, drops the padding: the object is 0x134 bytes again and matches\nretail.\n\nThe flag lives in SN_FLAG_UNITS for this unit only. A sweep of the other 66\nnear misses with the same flag changed nothing else; fun_00214a98 needs some of\nthe hazard NOPs retail keeps, so a whole-file flag cannot fix it.\n\n./verify-baseline.sh: PASS (e050581032e4bb3f20341307da5b69b76f1574910519155380ea771e55c3c0c9).\n\n* chore: refresh the progress report and the map for fun_001f2070\n\n  matched code       138,788 -> 139,096 of 340,608 B   40.75 -> 40.84 %\n  matched functions  816 -> 817 of 1,090\n  fuzzy match        70.78 -> 70.85 %\n\npython3 scripts/gen_progress_report.py --check: progress/report.json is current.\npython3 scripts/test_public_tools.py: 73 tests OK.","measures":{"fuzzy_match_percent":70.84782,"total_code":340608,"matched_code":139096,"matched_code_percent":40.837563,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1090,"matched_functions":817,"matched_functions_percent":74.954124,"complete_code":139096,"complete_code_percent":40.837563,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":60}},{"timestamp":"2026-09-26T17:33:24Z","commit_sha":"1a3e515945904d05ceef1392921576b7977fe678","commit_message":"docs: Refine warning message in README\n\nUpdated warning message formatting for clarity.","measures":{"fuzzy_match_percent":69.60165,"total_code":340608,"matched_code":136288,"matched_code_percent":40.013153,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1090,"matched_functions":810,"matched_functions_percent":74.31193,"complete_code":136288,"complete_code_percent":40.013153,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":58}},{"timestamp":"2026-09-26T17:22:09Z","commit_sha":"534c4a208dc9233c9c13f326224ab6ee971a3135","commit_message":"fix: one rename proposal per unit, and refresh the group assignment\n\nThe progress workflow failed to load the catalog:\n\n  ValueError: multiple grouping/name entries for source unit\n  audio/music/music_start_track_10000\n\nThe six track-start renames each ended up with two rows. They had one row before\n- an unresolved entry from the 2026-09-24 pass, carrying no name and no evidence\n- and the proposal this batch added. The rename tool's update_catalog_owners\nrewrites the unit of every entry that shares an address with a moved unit, so\nonce the move happened, both rows named the same unit. The rows were otherwise\nidentical, and the unresolved one held nothing, so it is dropped; the proposal\nwith the source analysis stays. The catalog is back to one row per unit.\n\nThe tool now refuses to write such a catalog instead of leaving the failure\nthree files away: find_duplicate_catalog_units checks the invariant that\nprogress_groups.py enforces, and a duplicate becomes an issue, so --apply exits\nwithout writing and names the unit. Five tests in test_public_tools.py cover\nit, including the pending-versus-promoted spelling of the same unit.\n\nload_module registers the module in sys.modules before executing it, because a\nmodule that declares a dataclass looks itself up there while the class body is\nevaluated and fails with \"NoneType object has no attribute '__dict__'\". That is\nwhy the new tests could not import the rename tool.\n\nprogress/report.json is refreshed because the renames moved six units into the\naudio/music group, and the committed report still listed FUN_00215440. Nothing\nis degraded: 136288 of 340608 configured bytes matched, 109 groups and 1090\nfunctions are unchanged, and the fuzzy figure rises from 69.54 to 69.60 percent.\nThe diff is 85 lines, all of it the group attribution of the six renamed units.\n\npython3 scripts/test_public_tools.py: 73 tests OK.\npython3 scripts/gen_progress_report.py --check: progress/report.json is current.","measures":{"fuzzy_match_percent":69.60165,"total_code":340608,"matched_code":136288,"matched_code_percent":40.013153,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1090,"matched_functions":810,"matched_functions_percent":74.31193,"complete_code":136288,"complete_code_percent":40.013153,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":58}},{"timestamp":"2026-09-26T16:11:44Z","commit_sha":"eb8a00095a87f323cff68a595e10c1ffda3311e4","commit_message":"docs: point the progress map, the badge and the prose links at the project page\n\nThe SVG and the decomp.dev badge linked to the bare domain, which lands on the\nsite's front page rather than on this project. Both now address\ndecomp.dev/mateuszklysz/Lombyte, as do the three prose references in\ndocs/progress-metrics.md and CONTRIBUTING.md.\n\nThe pitch drops the \"Lombyte reconstructs the original Emotion Engine executable\"\nwording in favour of \"Reconstructing the original executable in readable C, with\na native PC port as the long-term goal\", and the title no longer needs the\n<strong> wrapper now that the line is plain text.","measures":{"fuzzy_match_percent":69.53946,"total_code":340608,"matched_code":136288,"matched_code_percent":40.013153,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1090,"matched_functions":810,"matched_functions_percent":74.31193,"complete_code":136288,"complete_code_percent":40.013153,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":58}},{"timestamp":"2026-09-26T16:05:23Z","commit_sha":"d9f4acc4b1cf17107a4dd350dd400b69eb1c2544","commit_message":"docs: replace the moved README fragments with current reference documents\n\nThe front page no longer carries a build manual, a repository map or an\nexplanation of the progress numbers, so those became documents. Rather than\nfreeze the old prose verbatim, they are written against the checkout as it stands,\nand the three that only restated something else are gone:\n\n  removed  docs/about.md              the pitch is in the front page tagline; the\n                                      \"non-commercial research project\" framing\n                                      added nothing a reader can act on\n  removed  docs/readme-details.md     the per-unit walkthrough already lives in\n                                      CONTRIBUTING.md, which is linked from the\n                                      front page\n  removed  docs/repository-layout.md  both checkouts are mapped as a tree in\n                                      docs/project-map.md in the tooling repo\n  rewritten docs/building.md          toolchain, game files, make elf, the gate,\n                                      make iso, the generated-path notes, and the\n                                      env override table\n  rewritten docs/progress-metrics.md  what C_EXACT and C_FUZZY measure, what a\n                                      report unit is, the two verification levels,\n                                      oracles, and why 100 percent is not exact\n\nNeither document quotes a percentage. They are regenerated from every build and\nwould be stale the moment they were written down; the current figures live in\nassets/decomp_map.svg, progress/report.json and on decomp.dev, and the documents\nsay so instead of guessing. The retail boot hash is likewise referenced rather\nthan copied.\n\nThe one number that does appear is the identity of a file, not a measurement:\nthe tool versions, the paths, and the expected hash a build is checked against.","measures":{"fuzzy_match_percent":69.53946,"total_code":340608,"matched_code":136288,"matched_code_percent":40.013153,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1090,"matched_functions":810,"matched_functions_percent":74.31193,"complete_code":136288,"complete_code_percent":40.013153,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":58}},{"timestamp":"2026-09-26T12:24:41Z","commit_sha":"200f9bc4b6afabd5593d1e5736889a0453c616bd","commit_message":"decomp: 21 exact promotions (15 textbin, 5 SDK, 1 audio), init_dma as asm, staged NON_MATCHING bodies (#12)\n\n* decomp: promote 15 exact textbin units\n\nfun_002157d0, fun_002158a0 (music channel starts), fun_00227140,\nfun_002265d8, fun_00212d68, fun_001f0c50, fun_00200c80, fun_00200e08,\nfun_00200f90, fun_00200958, fun_00200080, fun_00200258 (HUD/GIF packet\nbuilders), fun_002216c0, snd_bank_load_from_ee_cb and\nsnd_send_iop_command_and_wait.\n\n* decomp: classify init_dma as intentional asm\n\nThe retail body is marked handwritten: trapping add with an explicit $at\nbase, which no EE-GCC front end emits.\n\n* decomp: stage improved NON_MATCHING bodies\n\n* chore: refresh the progress report and treemap\n\n* decomp: promote 6 exact units (5 SDK, 1 textbin)\n\nsceGsExecLoadImage, sceDmaPutEnv, sceMpegCreate, FindSubstring,\n_extensionAndUserData and snd_send_iop_command_no_wait.\n\n* decomp: stage improved NON_MATCHING bodies\n\n* chore: refresh the progress report and treemap","measures":{"fuzzy_match_percent":68.19338,"total_code":340608,"matched_code":132144,"matched_code_percent":38.796505,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1094,"matched_functions":796,"matched_functions_percent":72.76051,"complete_code":132144,"complete_code_percent":38.796505,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":58}},{"timestamp":"2026-09-26T11:28:21Z","commit_sha":"b597034c85a234e6bf94c2e876713bfaf5d0028c","commit_message":"docs: refresh progress report and treemap\n\nMatched code 34.81 -> 36.70 % (125,060 / 340,748 B), fuzzy 64.98 -> 66.15 %,\nmatched functions 68.58 -> 70.78 %, complete groups 53 -> 56 / 109.","measures":{"fuzzy_match_percent":66.15382,"total_code":340748,"matched_code":125060,"matched_code_percent":36.70161,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1095,"matched_functions":775,"matched_functions_percent":70.77625,"complete_code":125060,"complete_code_percent":36.70161,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":56}},{"timestamp":"2026-09-26T07:18:15Z","commit_sha":"7ec0f45c6df404c52f1af25e955cf622bb3ec42f","commit_message":"decomp: 17 exact promotions, 5 intentional-asm units, 20 staged NON_MATCHING bodies (#11)","measures":{"fuzzy_match_percent":64.98014,"total_code":340780,"matched_code":118624,"matched_code_percent":34.809555,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1098,"matched_functions":753,"matched_functions_percent":68.57923,"complete_code":118624,"complete_code_percent":34.809555,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":53}},{"timestamp":"2026-09-26T06:13:23Z","commit_sha":"9210ad55f260f1bad0401520b23940149e2a6efd","commit_message":"decomp: name the last FUN_ definitions; fix in-place renames in the rename tool (#10)","measures":{"fuzzy_match_percent":62.71488,"total_code":342436,"matched_code":113500,"matched_code_percent":33.14488,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1103,"matched_functions":736,"matched_functions_percent":66.727104,"complete_code":113500,"complete_code_percent":33.14488,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":53}},{"timestamp":"2026-09-25T20:34:08Z","commit_sha":"ad0f21bda0222660cb2ebfc4087ac6dad56280d8","commit_message":"decomp: 38 textbin exact promotions and 19 staged NON_MATCHING bodies (#7)\n\n* decomp: promote 8 textbin units (C_EXACT 106,548 B)\n\nPlain C rewrites, each measured exact on its registered route; the\nfull-ELF check passes (e0505810...c0c9). C_EXACT is 31.11 % of\nrecoverable C (fuzzy 59.28 %).\n\n- handle_camera_collision_with_hero, submit_audio_stream_io_request and\n  vu1_sync_chain in their semantic folders.\n- fun_00116da8 (newlib vfprintf), fun_00217048 (pad setup),\n  fun_00208840 (state step), fun_001f0bd0 (debug text queue),\n  fun_001fecc8 (pair table lookup).\n\n* fix: call load_irx_module's SIF helpers by their promoted names\n\nThe callees func_0011C8C8, func_00118B20, func_00118B10, func_0011CD78 and\nfunc_0011C9B0 have no func_ alias any more, so a clean build of main did not\nlink. They are sceSifAllocIopHeap, sceSifSetDma, sceSifDmaStat,\nInvokeIopStatus and InvokeStateInitializer.\n\n* decomp: promote 30 textbin units (C_EXACT 113,500 B)\n\nEvery unit re-measured 100/100/100 with zero instruction mismatches on its\nrecorded route before the move, and the full-ELF gate passes (SHA-256\ne050581032e4bb3f20341307da5b69b76f1574910519155380ea771e55c3c0c9).\n\nGameplay: find_id_in_terminated_table, detach_manipulator, patch_moby_gifs,\ncam_interp_values, update_all_cameras, fun_00203640 (moby class slot),\nfun_002191b8 (level exit), fun_0020baf0 (unlock conditions), fun_0021e110,\nfun_0021ea48, fun_00213358, fun_00213ed8, fun_00207a18, fun_00208408,\nfun_0020cfd0, fun_0022c830, fun_00226e58, fun_001fed30.\nRendering: reset_gs_registers, reset_gs_registers_pr, dma_moby_textures,\nfun_00228a30 (tie GIF remap), fun_00202800, fun_00231608 (display mode).\nAudio and video: audio_dec_end_put, pcm_callback, fun_002156d8,\nvi_buf_put_ts, vi_buf_stop_dma, fun_00232f20 (stash read-back).\n\nNotes:\n- The GIF/DMA packet pointer (D_00160F00, D_0015FF0C) is declared as a\n  one-field struct. As a plain pointer, gcc treats it as a fixed scalar that\n  a store through a struct pointer cannot alias, so it is not reloaded after\n  each tag word as retail does; volatile reloads it but keeps the final\n  store out of the jal delay slot.\n- fun_0020baf0 compiles a 10-entry switch table; it is placed at retail\n  0x1E8390 through RODATA_OVERLAYS, like dispatch_game_state_update.\n- fun_0022c830 and vi_buf_stop_dma call truncate_float_to_s32 and the\n  set_dma_channel_{3,4}_control_register helpers through their FUN_ labels.\n\n* decomp: stage recovered C into 19 pending units' NON_MATCHING branches\n\nStaged by the tools' sync_pending_bodies: each body replaced the #else branch\nonly after check-unit.py (the harness progress/report.json uses) measured it\nat least 0.5 higher than the body it replaced; the INCLUDE_ASM oracle is\nunchanged, so the linked ELF is not affected.\n\nLargest gains: fun_00204ef8 35.2 -> 99.2, enqueue_voice_request 0 -> 83.7,\nfun_00226670 9.2 -> 77.3, snd_bank_load_from_ee_cb 2.1 -> 44.6,\nfun_0021b6d8 39.1 -> 77.3, memcard_prepare_data 0 -> 53.1.\n\n* chore: refresh the progress report and treemap after the promotions\n\nmatched code 31.05 % -> 33.14 % (113,500 / 342,436 B), fuzzy 61.03 % -> 62.71 %\n\n* decomp: give the promoted and staged functions their semantic names\n\nThe 15 promoted units with semantic file names and the 9 staged NON_MATCHING\nbodies defined their functions as FUN_<address>. They now follow the tree's\nconvention: the C identifier is the unit's name, a prototype with\n__asm__(\"FUN_<address>\") keeps the emitted symbol, and the func_ alias takes\nits type from the named function. Units still named fun_<address> keep FUN_.\n\nThe full-ELF gate still passes (SHA-256\ne050581032e4bb3f20341307da5b69b76f1574910519155380ea771e55c3c0c9) and the\nstaged bodies measure the same on check-unit.py.","measures":{"fuzzy_match_percent":62.71488,"total_code":342436,"matched_code":113500,"matched_code_percent":33.14488,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1103,"matched_functions":736,"matched_functions_percent":66.727104,"complete_code":113500,"complete_code_percent":33.14488,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":53}},{"timestamp":"2026-09-25T19:52:22Z","commit_sha":"053e6738eb4a9b936d868beaf34b38d9beffba07","commit_message":"chore: refresh the progress report and treemap after staging\n\nprogress/report.json is the published number decomp.dev reads, and it is\ngenerated locally because CI cannot build the game. The 55 staged bodies plus\nthe cpr8 promotion move it:\n\n  fuzzy 59.13 % -> 61.03 %      matched code 30.86 % -> 31.05 % of 342436 B\n\nscripts/gen_progress_report.py --check passes, which is what the workflow runs\nbefore uploading it. Generation takes 37 s, because nothing caches a measurement\nper staged body: it re-measures every pending unit. A cache keyed on the hash of\nthe #else body would make this incremental, and that belongs on the game-repo\nside where another session is working.","measures":{"fuzzy_match_percent":61.03077,"total_code":342436,"matched_code":106320,"matched_code_percent":31.048138,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1103,"matched_functions":698,"matched_functions_percent":63.28196,"complete_code":106320,"complete_code_percent":31.048138,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":50}},{"timestamp":"2026-09-25T17:50:37Z","commit_sha":"63d7ee6d53f6ef21fe8ae5719e53295a11b11de4","commit_message":"chore: refresh the decomp.dev progress report after the verified baseline\n\nCI cannot build the game, so progress/report.json is generated locally and\ncommitted; the workflow only checks that it is current. It was stale against\nthe 2026-09-25 baseline: 342436 B matched (30.86 %), fuzzy 59.13 %,\n50 of 109 groups done.\n\nscripts/gen_progress_report.py --check now passes, which is what the\nworkflow runs before uploading it.","measures":{"fuzzy_match_percent":59.132683,"total_code":342436,"matched_code":105664,"matched_code_percent":30.85657,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1103,"matched_functions":697,"matched_functions_percent":63.191296,"complete_code":105664,"complete_code_percent":30.85657,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":50}},{"timestamp":"2026-09-25T13:15:04Z","commit_sha":"977b7f03eef01f6377cb410a878efe76b62fe2d3","commit_message":"decomp: promote 3 exact textbin units","measures":{"fuzzy_match_percent":58.760303,"total_code":342436,"matched_code":103052,"matched_code_percent":30.0938,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1103,"matched_functions":688,"matched_functions_percent":62.37534,"complete_code":103052,"complete_code_percent":30.0938,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":49}},{"timestamp":"2026-09-25T09:48:57Z","commit_sha":"9faf4ef84408635e2d19c4cfee36cbc2a0f1f149","commit_message":"chore: semantic function names (#6)\n\n* chore: group progress report by subsystem\n\n* decomp: migrate proposed function names with assembler labels\n\n* fix: keep build routing aligned with renamed units\n\n* decomp: group source units by semantic subsystem\n\n* chore: render progress as grouped treemap\n\n* decomp: align source layout with semantic groups\n\n* chore: use semantic aliases at C call sites\n\n* fix: generate oracles for semantic FUN aliases\n\n* fix: emit objdiff-compatible progress metadata\n\n* fix: preserve grouped unit metadata for decomp.dev","measures":{"fuzzy_match_percent":58.684284,"total_code":342436,"matched_code":102636,"matched_code_percent":29.972317,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1103,"matched_functions":685,"matched_functions_percent":62.103355,"complete_code":102636,"complete_code_percent":29.972317,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":48}},{"timestamp":"2026-09-25T08:57:36Z","commit_sha":"743cf0445bcdc66cbcbaed301b7493a9f545dd1e","commit_message":"chore: Semantic Function Names (#6)\n\n* chore: group progress report by subsystem\n\n* decomp: migrate proposed function names with assembler labels\n\n* fix: keep build routing aligned with renamed units\n\n* decomp: group source units by semantic subsystem\n\n* chore: render progress as grouped treemap\n\n* decomp: align source layout with semantic groups\n\n* chore: use semantic aliases at C call sites\n\n* fix: generate oracles for semantic FUN aliases\n\n* fix: emit objdiff-compatible progress metadata\n\n* fix: preserve grouped unit metadata for decomp.dev","measures":{"fuzzy_match_percent":58.684284,"total_code":342436,"matched_code":102636,"matched_code_percent":29.972317,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1103,"matched_functions":685,"matched_functions_percent":62.103355,"complete_code":102636,"complete_code_percent":29.972317,"complete_data":0,"complete_data_percent":0,"total_units":109,"complete_units":48}},{"timestamp":"2026-09-24T17:17:12Z","commit_sha":"2d70feab5c5fbe452baf624dee2df326b765cb7f","commit_message":"decomp: promote 8 textbin units (C_EXACT 685 / 102,636 B) (#5)\n\nPlain C rewrites, each measured exact on its registered route and gated\nby the full-ELF check (e0505810...c0c9).\n\n- fun_0011dc18: libgcc __do_global_ctors (gbl-ctors.h body), SDK compiler.\n- fun_001fee38, fun_001ff960, fun_0020c880: animation table lookups and\n  a moby's current and next frame pointers.\n- fun_00209298: DMA packet header check and initialisation.\n- video_dec_flush: end code appended to the MPEG ring buffer.\n- fun_001f5138: fog/alpha GS registers around a full-screen sprite.\n- fun_0012f368: file read through sceCdRead with retries.","measures":{"fuzzy_match_percent":58.684284,"total_code":342436,"matched_code":102636,"matched_code_percent":29.972317,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1103,"matched_functions":685,"matched_functions_percent":62.103355,"complete_code":102636,"complete_code_percent":29.972317,"complete_data":0,"complete_data_percent":0,"total_units":1103,"complete_units":685}},{"timestamp":"2026-09-24T16:47:56Z","commit_sha":"f303c8381998f287a7466ee1f52e86c2067ce043","commit_message":"decomp: promote 39 textbin units and refresh intentional-asm categories\n\n* decomp: promote 22 textbin units (C_EXACT 660 / 99,004 B)\n\nPlain C rewrites, each measured exact on its registered route and gated\nby the full-ELF check (e0505810...c0c9).\n\n- IOP RPC request wrappers fun_0012e368, fun_0012e308, fun_0012e4c0 and\n  fun_0012f108 build the request words on the stack.\n- newlib reentrant wrappers fun_00114000, fun_00114518, fun_00116108\n  (_read_r) and fun_001185d0 (_write_r) use the SDK compiler: retail\n  saves with sd/ld.\n- GIF tag writers fun_001fb3d0, fun_001fb680 and fun_001fb6e0 go through\n  a byte packet pointer that is re-read after every store.\n- fun_001ebec8 and fun_001ec3d8 dispatch through the moby class table.\n- fun_001f7a30, fun_0020ad38, fun_0020c828, fun_0020cc18, fun_00216b68,\n  fun_0023c660, fun_0023d140 (plus its D_0023D140 data alias),\n  fun_0012d9d8 and video_dec_put_ts.\n\n* config: classify 103 hardware-only units as intentional asm\n\nThe intentional_asm list is now derived from the 2026-09-24 source\nquality audit (129 -> 232 units). The added units contain instructions\nthe EE-GCC C front ends cannot emit: VU0 macro-mode COP2 (qmtc2, vcallms,\nlqc2/sqc2, v*), EE MMI packed operations, or addi (opcode 0x08), each\nconfirmed on the raw retail words. They leave the recoverable-C\ndenominator: C_EXACT is 660 units / 99,004 B, 28.91 % of recoverable C\n(fuzzy 57.85 %). Map and decomp.dev report regenerated.\n\n* decomp: promote 17 textbin units (C_EXACT 677 / 101,176 B)\n\nPlain C rewrites, each measured exact on its registered route and gated\nby the full-ELF check (e0505810...c0c9). C_EXACT is 29.55 % of\nrecoverable C (fuzzy 58.37 %).\n\n- Callback lists fun_001ebcf0, fun_001f4650, fun_001f46c8, fun_001f4740\n  and fun_001f4808.\n- Animation queue fun_001ff308, fun_001ff418 and fun_001ff500.\n- Packet writers fun_001f5210 (RGBA packed as u64), fun_001fb2d0 and\n  fun_00233888 (VIF UNPACK header plus payload copy).\n- Sound handle callbacks fun_002169c0 and fun_00216a20.\n- fun_00209370 and fun_002043b0 (level chunk load), fun_0020acc0\n  (16-bit CRC) and fun_001ff658 (name buffer).","measures":{"fuzzy_match_percent":58.36641,"total_code":342436,"matched_code":101176,"matched_code_percent":29.54596,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1103,"matched_functions":677,"matched_functions_percent":61.37806,"complete_code":101176,"complete_code_percent":29.54596,"complete_data":0,"complete_data_percent":0,"total_units":1103,"complete_units":677}},{"timestamp":"2026-09-24T15:13:30Z","commit_sha":"eff8029e2dc725346c0254024a3d42031f132664","commit_message":"fix: skip the progress artifact upload on pull requests (#3)\n\ndecomp.dev reads the report artifact only from runs on main, so pull\nrequests keep the freshness check and objdiff validation but no longer\nupload an artifact nobody consumes.","measures":{"fuzzy_match_percent":50.640224,"total_code":390088,"matched_code":97248,"matched_code_percent":24.929758,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1206,"matched_functions":638,"matched_functions_percent":52.902157,"complete_code":97248,"complete_code_percent":24.929758,"complete_data":0,"complete_data_percent":0,"total_units":1206,"complete_units":638}},{"timestamp":"2026-09-24T15:08:35Z","commit_sha":"f18ea57e965bf7e88630871cc3b230b05b07c587","commit_message":"Promote 25 SDK units and publish a decomp.dev progress report (#2)\n\n* config: ignore D_FFFFFF and D_FFFF loop-counter constants\n\nsplat paired the lui/addiu of WaitDma's 0x1000000 retry counter and\nsceDbcInit's 0x10000 bind-retry delay loop into fake D_FFFFFF/D_FFFF\naddresses. Like D_FFFFF, they are plain constants.\n\n* decomp: promote 25 SDK units matched against Sony archives (C_EXACT 638 / 97,248 B)\n\nEach unit is byte-identical to a member of the Sony EE SDK 2.5 libraries\nretail linked (libdma, libgraph, libdbc, libkernl, libcdvd, libmc, libmpeg,\nlibpad2, libvib); the archive objects gave object layout, volatility,\nbitfield widths and argument shapes. _dualPrimeVector and _motionVectors\nfollow the MSSG mpeg2decode sources libmpeg derives from.\n\nsdk: WaitDma, sceGsSyncV, sceGszbufaddr, sceMpegAddStrCallback, _doCSC,\n_ipuVdec, _waitBdecOut, mceStorePwd, scePad2GetButtonProfile,\nscePad2GetState, scePad2CreateSocket, sceVibGetProfile, _pictureData0,\n_nextHeader, _dualPrimeVector, _motionVectors, sceDbcInit, sceMcInit,\nsceSifRebootIop, sceSifResetIop, sceSifInitRpc.\ntextbin (SDK compiler via SDK_COMPILER_UNITS): fun_00124a20 (DPRINT),\nfun_0011c938 (sceSifFreeSysMemory), fun_001206d8 (_sceCd_cd_callback),\nfun_0011ace8 (_sceRpcGetPacket).\n\nPromoted with promote-unit.py (fresh exact measurement on each unit's\nregistered sony-2.9 route). Full-ELF gate: reconstructed SCUS_971.99 matches\nretail (e050581032e4bb3f20341307da5b69b76f1574910519155380ea771e55c3c0c9).\n\n* chore: publish a decomp.dev progress report\n\ndecomp.dev reads objdiff's report.json from a \"<VERSION>_report\" artifact\non the default branch. The new progress workflow does not build the game and\nuses no secrets: it checks that the committed progress/report.json matches\nthe repository (scripts/gen_progress_report.py --check), validates it with a\npinned objdiff-cli and uploads it as SCUS_971.99_report.\n\nThe report is generated locally after make elf (make progress). It counts\nonly C_EXACT units as matched (the baseline objdiff report shows\nassembly-backed units at 100 % because they build from their oracle),\ncarries measured similarity for pending units, leaves intentional asm out\nand splits Game / Sony SDK categories: 97,248 / 390,088 B (24.93 %),\nC_FUZZY 50.64 %, matching assets/decomp_map.json. It holds names, symbols,\naddresses, sizes and percentages only; no retail bytes.\n\n* docs: forbid agent trailers, session links and agent identities in commits\n\nSessions are private and this repository is public. The commit-msg hook\ndrops Co-Authored-By and Claude-Session trailers, rejects any remaining link\nto an AI chat or agent session and rejects an AI agent identity as author or\ncommitter. The commit standard states the rule for commits, pull requests\nand review comments.","measures":{"fuzzy_match_percent":50.640224,"total_code":390088,"matched_code":97248,"matched_code_percent":24.929758,"total_data":0,"matched_data":0,"matched_data_percent":0,"total_functions":1206,"matched_functions":638,"matched_functions_percent":52.902157,"complete_code":97248,"complete_code_percent":24.929758,"complete_data":0,"complete_data_percent":0,"total_units":1206,"complete_units":638}}]