Skip to content

feat(functional): second backfill round for the native port - #393

Draft
Veradictus wants to merge 21 commits into
masterfrom
port/backfill-2
Draft

Veradictus wants to merge 21 commits into
masterfrom
port/backfill-2

Conversation

@Veradictus

Copy link
Copy Markdown
Member

Second round of functional C for the native port (OpenRAC #212), plus the port-only fixes moved upstream. Matched code is untouched apart from byte-neutral spellings.

  • feat(src): match shared steering update and repair retained large functions #391 follow-up: func_002859C8 keeps the 64-bit TEX0 words of func_0028E640 and func_0027C878 (they were truncated to int); func_0034B2C8 calls sprintf variadically. Both re-gated SAME.
  • 46 new functional rows (403 in all): boot and level functions the game reaches with no C, each fcheck SAME on retail states with every unrun block read against retail. Includes the two per-level copies that differed (func_L05_0041EF00, func_L15_0042EFE0).
  • Port-only rewrites upstreamed: the master orb word (D_001B17AC), hero update names, menu literal addresses, HUD prompt names, SDATA aliases, func_0027C878's width; plus byte-neutral src spellings (func_0028EA58 returns int, func_0027EA28, func_0027CFD0, D_00256368, func_002A0F48(u8 *)).

Checks (box1): US, US2 and PAL each build 28/28 strict; 339 unit tests; tests/check_repository.py.

…o HUD rows

func_002859C8 declared func_0028E640 and func_0027C878 as returning int and
passed their results to func_0028F410 and func_0027FC70 as int, but both
build a 64-bit GS TEX0 word (dsll32/ld) that the callee keeps whole: on the
host the high half was lost. func_0027FAA8 returns int. func_0034B2C8
declared the formatter func_00115DA8 with fixed arguments; it is variadic.
Prototypes as llesieur99's #391 found them in the near-miss drafts.
VU0 vector helpers written as plain floats (func_00282C90, func_00283360,
func_002836E8), the float split func_00283CC8, newlib's sqrt wrapper
func_00131424, the mission list fill func_0029B910, the orientation update
func_002EE000, the nibble clear func_002E3360, SpawnBoltByValue
func_00302470 and the deformable-grid rebuild func_00303210. Each is SAME
on the gate's captured calls; the blocks no call ran were read against
retail.
The event record walk func_002B9390, the weapon grid draw func_003478F0,
the panel setup func_003486A8, the gadget-deployed moby update
func_003216E8, the pickup payout func_002A6C58, and the radial weapon
menu draw and input (func_0028D1E8, func_0028CCE0). SAME on the gate;
unrun blocks read against retail. Fixes over the near misses: a delay-slot
store before func_00348578, the radial menu's default table at 0x1A8DB8,
its held-button call, and data names the drafts had at level 0's places.
func_L00_00300618 (level data loader and moby spawn), func_L00_0036EF68,
func_L00_002FE268, func_L00_003C27A0, func_L00_002D4E58, func_L00_0042A4E8,
func_L01_00394148, func_L01_003209F8, func_L01_00399510 (rain and snow
emitter), func_L02_002EFB60, func_L02_00333480 and func_L02_00389F70.
SAME on their own level's captured calls; unrun blocks read. Fixes over
the drafts: the loader's heap store only on a first load, func_00283098's
matrix argument, the save bitmaps at 0x19B2E8/0x19B4A8, 1.57 in
func_L00_002D4E58 and level 0's copy func_0029F978 there.
Barlow's water ripple step and its DMA chains (func_L04_0032F62C,
func_L04_0032F994), func_L04_003C4050, five level 5 routines (effect draw,
controller, camera rates, camera position, lock-on pick), the two
per-level menu copies func_L05_0041EF00 and func_L15_0042EFE0 (their row
text ids and text styles differ from level 10's), func_L06_00382608,
func_L09_003F7CE0, func_L13_0041FBE0 and func_L19_004203F0. SAME on the
gate's captured calls; unrun blocks read against retail.
OpenRAC's games/rac2 game.json rewrote these on every sync; they belong
here. func_003136D0's master orb is the executable's D_001B17AC, which
moves with each level (level 0's D_L00_001B1AEC was read in every level).
func_L00_002A9460 calls func_L00_002A75D8 and func_L00_002A76B8 by name.
The menu rows compare with D_ and func_ names instead of literal
addresses (func_002CBC58, func_002D6F38), func_003120C8 and
func_L06_00403130 drop SDATA aliases for plain globals, func_0034DB98
keeps func_0027C878's 64-bit result, func_0028EA58 returns int, and the
HUD prompt drafts name 0x1A8C60/0x1A8C64 and 0x1B1D48. AGENTS.md points
at OpenRAC's docs/port/BACKFILL.md.
Byte-neutral spellings that OpenRAC's game.json applied on every sync:
func_0028EA58 returns int, Ff67aa9df_FUN_0027EA28 is func_0027EA28,
ref_L00_00370408_00 is func_0027CFD0, func_002A0F48 has a typed
parameter and D_00250000 + 0x6368 is D_00256368. The three releases
build strict.
… and 12 actors

func_L04_00419918 (race controller: setup, countdown, race sub-states,
route and exit), func_L08_003CDF98 (the rider NPC's state machine) and
func_L12_003E2460 (path-walking enemy). SAME on the gate's captured calls,
which run only part of each; every unrun block was read against retail.
Fixes over the drafts: level 8's func_002A7750-only exit from state 6, the
func_002ABBB8 stack arguments, state 10's min.s limit, the 0.07 particle
size, byte and word widths, level 12's height floor from the target
waypoint and the byte argument to func_L12_00408050.
@bytematchdev

bytematchdev Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

ByteMatch progress report

SCES_516.07

Code matched 54.15% · 3.09 MB of 5.70 MB
Fuzzy match 54.15%
Functions 6,996 / 8,672
Data matched 0.00%
Units complete 958 / 1,196

No function changes.

SCUS_972.68_v2

Code matched 81.01% · 4.52 MB of 5.58 MB
Fuzzy match 81.01%
Functions 7,595 / 8,634
Data matched 0.00%
Units complete 973 / 1,156

No function changes.

SCUS_972.68

Code matched 84.74% · 4.68 MB of 5.53 MB
Fuzzy match 84.74%
Functions 7,760 / 8,579
Data matched 0.00%
Units complete 924 / 1,018

No function changes.

Commit 6e73485 · Ratchet & Clank: Going Commando on ByteMatch

Add, subtract, scale, lerp, absolute value, clip flags and the constant
stores of the vector library (func_00282A18 to func_00282D60), written as
plain floats in the VU's operation order, w lanes as the code leaves
them. Each is SAME on the gate's captured calls; the few instructions no
call ran were read against retail.
Divide with the VU's divide-by-zero, dot product, squared distance,
vector times matrix, byte and halfword unpacking, byte sum, matrix copy
and multiply, angle add with wrap, the sphere-in-view test against
D_001B92C0 and func_00278E78's slot read. SAME on the gate's captured
calls; unrun instructions read against retail.
func_00282C10 (sqrt of |x|) and func_00282E20 (length of a vector's x and
y; retail squares z but never adds it). SAME on the gate's captured
calls, checked through the gate's sqrt.s stand-in for sqrtf, as
fcheck_gate.py's test copies do.
Euler-angle rotation matrix (func_00283430), the light colour blend
func_002A04E8, the moby grid's block bitmap and cell moves (func_002A0B88,
func_002A0C68), the part matrix copy func_002A3F10, the camera
environment region lookup func_002A6640, the DMA channel reset
func_0029D050, the mip upload packets func_002E2988, the light overlap
list func_002F4FA0, the attachment point list func_002DFD88, the GS path
sync wait func_001244B8 and the Z, X and Y rotation matrix products
(func_00129218, func_001292C0, func_00129368). Plain floats in the VU0
order; SAME on the gate's captured calls (the sqrt ones through the
gate's sqrt.s stand-in); unrun blocks read against retail.
Level-only copies of the vector library in levels 0, 2, 3, 4 and 22:
squared length, point in sphere, xy clamp, packed s16 scale, subtract,
xy distance, 3x3 and 4x4 matrix arithmetic, Barlow's water block unpack
and matrix blend. SAME on their own level's captured calls; unrun
instructions read against retail.
The port's host routine for the moby joint chain takes two game
addresses; func_002A3F10's pointer prototype clashed with it in the
port's build. Same call, same arguments; SAME on the gate.
The vendor: opening it (func_002F8178), its list input (func_002F93B0),
row price (func_002F6510), fading text (func_002F97A0), icon strip
(func_002F9C80) and 3D preview (func_002FB1A0), captured from retail at a
level 3 vendor; with the trail ribbon func_00281A08 and the text draw
func_002D53F0. SAME on the gate's captured calls; unrun blocks read. The
armour preview after func_002923C0 has no state that returns.
func_L02_003CC7B0 (a companion moby's update; its per-frame
func_002B3BA8 call had its condition inverted), func_L00_00341FA8 (nearest
path segment), func_L01_003801B8 (rotating quads), func_L22_003A2160
(path steering), func_L22_003A5018 (the arena HUD, its 45 data names by
address and func_L00_0030CF60 on every path) and func_L11_00453358 (a
flying enemy, rewritten from retail). SAME on their own level's captured
calls; every unrun block read against retail.
…vel routines

The hand-written line and sphere collision (func_002761F8 CollLine,
func_00277258 CollSphere), the moby gather func_00277F48, the GS memory
slot allocator func_002F35B0, level 0's two-frame bone blend
func_L00_00314D40 and stream switch func_L00_0032D208, and level 2's
camera-facing sprite packet func_L02_00364A18. SAME on the gate's captured
calls; every unrun block read against retail. The two sphere routines
keep the outcode word retail leaves in $a3 for a rejected triangle, which
a later cache entry stores.
…e does

The port's host replacement of the joint chain is int func_002A4078(gaddr,
gaddr); func_002A3F10's void declaration still clashed with it. SAME on
the gate.
The port's prototype is int func_002A4078(gaddr, gaddr), gaddr unsigned;
int arguments still clashed. SAME on the gate.
…r and the pose snapshot

The status HUD element func_0034AA30, level 22's boss update
func_L22_0039D708 (four slips fixed in code no capture runs, among them
a fall-through after the moby frees itself), the pose snapshot
func_002A2450, the per-bone blend func_L00_00316F60 and CollCylinder
func_L00_002E0200. SAME on the gate's captured calls; every unrun block
read against retail.
The game and level main loops, the level change, archive, file and
level loaders, the FMV player, the menu state entry, func_L00_002B30E8,
func_L00_002EDCF0, level 3's func_L03_0038AB30, the glow sprites
func_L00_003FA858, Barlow's water lighting func_L04_0032F3C0 and the
moby collision pose func_002A3110. None has a gate verdict: retail never
returns within the gate's budget, no capture calls them, only another
level's copy has states, or (func_002A3110) the only difference is a
save of the hand-written callers' registers. Each was read in full
against retail by two readers; each header says why it is unchecked.
Host routines are declared as the port defines them.
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