Skip to content

Match 198 NTSC-U functions converted from their PAL matches - #97

Open
LucienTo wants to merge 1 commit into
OpenRAC:mainfrom
LucienTo:matches-batch-2
Open

LucienTo wants to merge 1 commit into
OpenRAC:mainfrom
LucienTo:matches-batch-2

Conversation

@LucienTo

@LucienTo LucienTo commented Nov 4, 2026

Copy link
Copy Markdown

Adds US sources for 198 NTSC-U functions that were already matched on PAL in src/pal/ but had no US source: 1 in src/core/, 197 in src/game/. The C is the PAL contributors' work (sources added by Shaar, Joshua Nierentz, Sumaiter, chistianh and Kryštof Malinda, in #77, #81, #84 and #85 among others), with every address rewritten to the US one. One commit.

Converting PAL C to US

src/ is written against SCUS_974.65, and tools/match_map.py finds a US function's PAL twin by its code, so a US source counts on both discs. The reverse does not happen: the US map and audit leave src/pal/ out, so a function matched only there stays unmatched on NTSC-U. The C cannot simply be reused, because it names addresses (func_XXXXXXXX, D_XXXXXXXX), which differ between the discs. This batch converts the PAL sources to US. In rac1-decomp, tools/version_sync.py carry does the same job, copying one version's C to the versions with the same code:

  1. Pairing. A PAL function in src/pal/ is paired with a US function that has no source yet and the same size and the same tools/inventory.py fingerprint (identity(): address fields masked, everything else compared). 292 pairs were found; functions in open PRs, Match 26 NTSC-U functions #94 included, were left out.
  2. Address map. The two functions' assembly (tools/asm_programs.py) is the same instruction for instruction apart from addresses, so lining them up gives PAL -> US for every address the code references: jal targets, $gp offsets (PAL $gp 0x2259FF and US 0x22597F, from .reginfo), and the addresses lui + addiu/load/store pairs build.
  3. Rewrite. Every func_/D_ address in the PAL source is replaced from that map, and the file is written under its US address. A source whose addresses do not all map exactly is skipped, never guessed: 219 of the 292 converted.
  4. Check. Each converted file was checked with tools/check_func.py on the US disc: 206 MATCH.

Left out:

  • seven conversions whose PAL sources credit cross-game reference code (config/pal/crossgame_sources.tsv), until their US credit rows are set up;
  • one whose US file name already exists (src/game/00506B70.c);
  • the 13 that did not compile or match, and the 73 with unmapped addresses.

The conversion scripts are not part of this PR. If it would help, I can propose them as a tool for converting PAL batches to US, which would be rac4's counterpart to rac1's carry.

$gp globals that a PAL file defines (docs/LEVERS.md) are defined in the US file too, under their US addresses.

Also in this PR

  • Eleven near misses that these now replace are removed from nonmatching/, with their README rows.
  • Progress, US: matched functions 5,435 -> 5,633, matched code 414,340 -> 442,332 bytes (7.17% -> 7.65%).
  • Progress, PAL: 6,032 -> 6,039 functions. The 7 added had no PAL source before and are matched by their US twins now. Functions already matched in src/pal/ are not counted twice.

Validation

  • Clean full build with tools/build.sh (6,439 translation units through the unchanged tools/cc.sh); tools/match_map.py --write for both versions: all 198 are match on NTSC-U.
  • tools/audit_relocs.py reports nothing for any of the 198, so every converted address agrees with the US binary (only its existing entries remain).
  • tools/audit_matches.py lists 24 of them with a size different from the old config/functions.tsv. That list ends each of these functions early, while config/us/functions.tsv and both maps have the full size, at which they match. Example: func_0053F550 is 64 bytes in the maps against 20 in the old list.
  • tools/progress.py --check passes for both versions, and git diff --check is clean.

Generated files

  • The maps and reports were regenerated with match_map.py and progress.py without the local libm objects, as the committed maps are.
  • Eight unrelated level-code near misses score near/none differently in this environment; their rows are left as committed.
  • This PR and Match 26 NTSC-U functions #94 both regenerate the same maps and reports. Whichever merges second needs them regenerated; I can do that on request.

No compiler-pipeline changes, retail data, extracted binaries or assembly listings are included.

🤖 Generated with Claude Code

Each of these functions was already matched on PAL in src/pal/ and has a US
twin with the same code: the same size and the same tools/inventory.py
fingerprint (address fields masked). The PAL source was taken over with every
func_/D_ address rewritten to the US one, from a PAL -> US map built by lining
the two functions' instructions up (jal targets, $gp offsets and lui-built
addresses). A source address with no counterpart in that map was not guessed:
those functions were left out. 1 lands in src/core/, 197 in src/game/. The C
itself is the work of the authors of the src/pal/ files.

Left out: seven ports whose PAL sources credit cross-game reference code
(config/pal/crossgame_sources.tsv), until their US credits are set up; the
functions in open PRs, OpenRAC#94 included.

Eleven near misses they replace are removed from nonmatching/ with their README
rows. Maps and reports regenerated for both versions without the local libm
objects, as the committed maps are; unrelated rows whose score differed in this
environment are left as committed. US: 5435 -> 5633 matched functions
(+27,992 bytes); PAL: 6032 -> 6039.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant