Kill the 48-byte loop lead: the function takes no pointer arguments

Finished the task I named last commit rather than leaving it as a lead.

Camera_CollPrimTest is declared Camera_CollPrimTest(void *prim, void *grid) --
two pointer arguments, which in MIPS arrive in $a0 and $a1.

The function's prologue is at 0x002db078, matching the +0x70 teardown at
0x002db354. The two instructions after it:

    0x002db078: addiu $sp, $sp, -0x70
    0x002db07c: lw    $v1, -0x3f4c($v0)    <- $v0, not an incoming argument
    0x002db080: addiu $a0, $zero, 0x6f     <- $a0 set to a constant

$v0 is caller-saved scratch, not an argument register, and $a0 is overwritten
with the constant 111 on the next instruction. No void* reaches this function, so
it is not Camera_CollPrimTest, whatever the assert table labels it.

It reads four consecutive words from boot memory -- 0x1a7348 through 0x1a7354 --
all below the level program base at 0x001A7C80, which is the boot's resident
region and identical in every program. A different data source from the collision
payload, and the 48-byte stride loop belongs to whatever that structure is.

So the lead is dead on evidence rather than on doubt, and both routes the decomp
appeared to offer are now closed:

    Camera_CollPrimTest  @ 0x001E7A50   lands in NOBITS, all zero
    GridOutOfBounds      @ 0x002db350   a function with no pointer arguments

Neither address reaches the collision parser. Worth noting how cheap the check was
once the tool worked: three instructions past a prologue is enough to disqualify a
function whose name asserts a signature. The expensive part was not the analysis,
it was the disassembler that stopped after five words and made everything look
empty.

The route that remains is the one already recorded -- find how the code addresses
the assert STRING at 0x001a8998 in .lit, which is not a $gp-relative load and is
not a symbol address in either table. Note that the string and the code are five
megabytes apart in different sections, so whatever reference exists is not a
simple local reference, and that is the thing to look for.
This commit is contained in:
2026-10-14 03:18:02 +02:00
parent 2f5979e652
commit 66a96111d7
+34 -9
View File
@@ -2986,16 +2986,41 @@ A loop over records of **48 bytes**, reading a float at `+12` and accumulating,
guarded by a count at `($s1)`. `lui $at, 0x3f80` / `mtc1 $at, $f22` sets `f22` to
1.0f, which is a minimum-height clamp.
**This is not claimed to be the collision grid.** It is a strided float loop
next to an assert the decomp labels `CameraCollPrimTestGridOutOfBounds`, and that
is a lead, not an identification. The gap between them is exactly the gap this
log keeps tripping over: a plausible address near a plausible assert is not a
named function. Confirming it needs the function's arguments traced back to the
collision payload, and the grid's two leading `u16` dimensions (level 0 is
11 x 33) have not yet been shown to drive the count at `($s1)`.
### It is not the collision grid, and the signature says so
Recorded as the most concrete route currently available, with its verification
gap stated rather than skipped.
This is checked rather than assumed. `Camera_CollPrimTest` is declared
`Camera_CollPrimTest(void *prim, void *grid)` -- two pointer arguments, which in
MIPS arrive in `$a0` and `$a1`.
The function's prologue is `0x002db078: addiu $sp, $sp, -0x70`, matching the
`+0x70` teardown at `0x002db354`. The two instructions after it are:
0x002db078: addiu $sp, $sp, -0x70
0x002db07c: lw $v1, -0x3f4c($v0) <- $v0, not an incoming argument
0x002db080: addiu $a0, $zero, 0x6f <- $a0 set to a constant
`$v0` is caller-saved scratch, not an argument register, and `$a0` is
immediately overwritten with the constant 111. **No `void *` reaches this
function**, so it is not `Camera_CollPrimTest` whatever the assert table labels.
It reads four consecutive words from boot memory instead -- `0x1a7348`,
`0x1a734c`, `0x1a7350`, `0x1a7354` -- all below the level program base at
`0x001A7C80`, which is the boot's resident region and identical in every
program. That is a different data source from the collision payload, and the
48-byte stride loop belongs to whatever that structure is.
So this lead is dead, and it is dead on evidence rather than on doubt. Both routes
the decomp appeared to offer are now closed:
| route | status |
| --- | --- |
| `Camera_CollPrimTest` at `0x001E7A50` | lands in NOBITS, all zero |
| `CameraCollPrimTestGridOutOfBounds` at `0x002db350` | a function with no pointer arguments |
Neither address reaches the collision parser. What remains is the route already
recorded: find how the code addresses the assert **string** at
`0x001a8998` in `.lit`, which is not a `$gp`-relative load and is not a symbol
address in either table.
### The disassembler needed fixing first