Skip to content

Decomp we object0 - #76

Merged
roengstrom merged 5 commits into
mainfrom
decomp-we_object0
Sep 1, 2026
Merged

Decomp we object0#76
roengstrom merged 5 commits into
mainfrom
decomp-we_object0

Conversation

@roengstrom

Copy link
Copy Markdown
Owner

No description provided.

1028 instructions, the largest world nonmatching: one long init followed
by a frame loop whose every exit is a break that records where control
goes next, then a shared teardown tail. The six huge "backedges" are not
loops -- they are those breaks, with their bodies placed ahead of the loop.

Two spellings the match turns on: the scratchpad stack switch around
renderWorldMapFrame is inline asm (there is no way to express a stack
switch in C -- the same device as fe_object1's SCRATCH_STACK_ENTER and
common.h's GP_* family), and declaring $t0 clobbered there changes which
temp the camera-magnitude multiply gets 900 bytes away.

Names for what the loop does: the map display modes are what the player
sees -- the corner globe, the transparent square, the full-screen map --
and with those named the screen geometry and the two edge-detected pad
bits read plainly. Slot gains the SceneState field the loop saves into,
carved from a pad.

Fixes the declarations the unit tripped over on the way: a second,
void-returning VSync in we_object2.h that contradicted the SDK;
D_8005F146 living in a field header while field, world and battle all use
it; D_800C9868 typed WorldPos when it is copied whole as 16 bytes and fed
to GTE routines; and InitGeom, SquareRoot0, SetDispMask and
deactivateBattleCmd being called by raw address.
Seven functions were declared in more than one place with signatures that
disagreed, so each unit compiled happily against its own reading. Six are
now declared once, by the unit that defines them, and the callers include
that header:

  func_800AC0A0 -> we_object5.h, the definition's own signature. Its two
    callers had invented PosDesc and Velocity for the arguments; both are
    VECTOR and SVECTOR field for field, so they are gone.
  func_800ACC68 -> we_object6.h. The asm dereferences arg 1 at +0x14,
    which is MATRIX.t[0], and we_object6's own call site was casting an
    SVECTOR[] to u8 * to satisfy its version.
  func_800ACD38 needed no declaration at all: with none in scope the call
    is C89 implicit int, which is the view that matches and evidently what
    the original had. A commented-out include marks it.
  func_800B0010's caller looked like it passed nothing -- but the jal's
    delay-slot nop proves a0 was live going in, so func_800BD6EC takes the
    kind and forwards it.
  func_800A7E74 does take the scene context, it just ignores it. A (void)
    definition and one with an unused parameter compile identically, so
    the (void) reading was never evidence.
  func_800B01A0's every argument comes from the asm: two s16, a VECTOR *
    handed to worldPosToCell, an SVECTOR * written at +0/+2/+4, and two
    NULL-checked output pointers.

Twelve more were declared identically in two or three headers, three of
them battle or main-binary symbols that world headers had no business
re-declaring. Removing such a declaration is not obviously safe here: gcc
2.8 accepts the call anyway as implicit int, silently and often without
changing a byte. Eleven such calls appeared while doing this and each is
now covered by a real include, checked by diffing -Wimplicit output
against the same tree at HEAD.

we_object3's seven externs for functions other units own are gone too;
WorldSprite and WorldSpriteRec move to we_object3.h since we_object6's
func_800B21EC takes one.
Thirty includes carried a trailing note naming what they supply. They rot
as soon as the unit uses something else from the header, and they drift:
inserting an include above one moves the note onto the wrong line. One had
ended up reading

    #include "world/we_object11.h"   /* D_800D23D0 */

for a symbol that comes from we_object5.h.

The same habit produced status narration -- "still assembly", "the readers
are asm", "defined below; its only caller is" -- which every decomp
session falsifies a little more and nobody goes back to correct. Two were
already wrong: we_object3.h still described func_800987D8 as assembly
reaching its callees through the linker, when it is C and includes that
header directly.

contrib_review gains rule 11 covering both, since they kept recurring: a
comment earns its place only by carrying what the code cannot -- what a
value means, why a spelling is load-bearing, or a measured fact.
Signed-off-by: rengstrom <engstrom.robin@gmail.com>
@roengstrom roengstrom self-assigned this Sep 1, 2026
@decomp-dev

decomp-dev Bot commented Sep 1, 2026

Copy link
Copy Markdown

Report for SLUS_008.92 (cfb1f4b - fb4ff8d)

📈 Matched code: 44.85% (+0.35%, +4112 bytes)

✅ 1 new match
Unit Item Bytes Before After
ovl/world/we_object0 func_800987D8 +4112 0.00% 100.00%

@roengstrom
roengstrom merged commit 15eff07 into main Sep 1, 2026
1 check passed
@roengstrom
roengstrom deleted the decomp-we_object0 branch September 1, 2026 21:12
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