3 Commits

Author SHA1 Message Date
cecilarmitais
d27a73870e Decompile 28 more callees; clear 21 asm files entirely
Clears asm/main_02003DB8.s, main_0200BC60.s, main_020276C0.s,
main_020278C4.s, main_02048C5C.s, main_0204FA70.s, main_0205A340.s,
main_0205B39C.s, main_0205B478.s and twelve overlay_29 files, with their
.inc headers and main.lsf entries.

sub_02048C5C lands in its own translation unit (extract_function.py -nm)
rather than merging into src/main_02048BB4.c: at -O4,s MWCC inlines
ReadStringSave when its body is visible in the same TU, which made the
function 16 bytes too long and shifted every overlay anchored below it.

Shared types corrected from the asm rather than from a guess:
- dungeon.h: four u8 field_0x2cb0c..f -> one u32 field_0x2cb0c (retail
  emits ldr/str, not ldrb/strb)
- window.h: struct unk_022A7A6C extended past 0xC; WindowBlock::unk24
  u32 -> void *
- main_02029A50.h: unkStruct_02029A50 gains u8 unk26
- dg_random.h includes dungeon_mode.h; struct unk_022E9298 moved verbatim
  into dungeon_range.h
- sub_0205B0A0 retyped (void *) -> (s32)

26 stale call-site externs across 20 files replaced with includes. Several
disagreed with the definition: sub_0205B39C was declared void(void*,void*)
where it is u8*(const s8*,s32), and three files declared CalcStatusDuration
with s32* where it takes const s16*.

asm/main_bss_020B3380.s gains a zero-length alias _022AAE74_2 at the same
address as _022AAE74. MWCC keys literal-pool entries on (symbol, addend)
and dedups, so the two identical .word entries the target holds require
two distinct C symbols; .space is untouched, so the layout is unchanged.

Authored by Claude (Opus 5) under human direction. Every landed function
was byte-compared against the assembly it replaced at object level before
building (build-tools/landcheck.sh), then confirmed by matching builds in
all three regions: build/pmdsky.us/pmdsky.us.nds: OK,
build/pmdsky.eu/pmdsky.eu.nds: OK, build/pmdsky.jp/pmdsky.jp.nds: OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 23:14:59 -07:00
cecilarmitais
7f6977e268 Decomp ten window accessors, including UpdateWindow and ClearWindow
Decompile from asm:

  sub_02027624   0x02027624      ClearWindow    0x02027B58
  UpdateWindow   0x02027AF0      sub_0202825C   0x0202825C
  sub_02027B1C   0x02027B1C      sub_02028270   0x02028270
  sub_020282C8   0x020282C8      sub_020282F4   0x020282F4
  sub_0202830C   0x0202830C      sub_02028324   0x02028324

Four bss symbols these functions index at stride 0xE0 are aliases into
WINDOW_LIST[0], not separate objects: _022A88E4 is +0x8, _022A88F0 is +0x14,
_022A88F8 is +0x1C and _022A8994 is +0xB8. The block from WINDOW_LIST to the end
of _022A8994 measures 0xB8 + 0x10C8 = 0x1180 = 20 * 0xE0, and every one of those
boundaries falls on a field boundary of the Window layout added earlier. That is
independent corroboration of the layout, from the linker rather than from the
struct definition.

Five of the ten do not reach score 0 on a scratch, and are landed anyway. Their
instructions all match; the only difference is the literal-pool word, which the
target names _022A8994 where C indexing WINDOW_LIST emits WINDOW_LIST+0xb8. Same
address, same relocation target, identical bytes once linked -- the scratch diff
compares symbol names, at a flat 5 per word, so ClearWindow and sub_02027B1C
report 10 and the three single-literal ones report 5. The matching build is what
settles it.

Which literal appears is decided by whether the index is constant. A constant
offset keeps the base symbol in the pool and puts the offset in the instruction;
a variable index folds the offset into the pool word because the index has to be
scaled separately. That rule cost a build here: NewWindowScreenCheck stores to
_022A7A6C at #8 and #0xa, and rewriting those two lines as _022A7A74[0] and [1]
to remove an apparent duplicate changed the pool word and failed main.sbin, with
no compile error and no overlay cascade. It is reverted, and both declarations
are kept, because the target keeps both.

sub_020282C8 writes width*8 and height*8 through an out parameter. It reuses
Point rather than adding a second two-s32 struct; the layout is identical and
the type already exists, but a size is not a coordinate, so read that as
structural reuse and not as a claim about meaning.

Two prototypes in the tree contradicted the ones landing here and are replaced
with includes: overlay_31_02382820.c declared UpdateWindow itself, and
overlay_31_02383880.c declared sub_020282F4 taking s8. Both objects are rebuilt
to confirm the retyping is byte-neutral rather than assumed.

Two more are left alone and are worth a later pass. overlay_13_0238BDA8.c
declares UpdateWindow and sub_02027B1C taking s8, and overlay_25_init.c declares
both taking char *; the second is a genuine mistyping, since the value it passes
is a window id, but correcting it means retyping ov25_0238B414's own parameter
and its callers, which is a larger change than this batch. The s8 declaration in
overlay_13 carries an upstream annotation identifying sub_02027B1C, which is
worth keeping in place rather than deleting to make a byte-neutral edit.

No comments are added to any pmd-sky file.

Authored by Claude (Opus 5) under human direction. Confirmed by a matching
build with both overlay_31 objects rebuilt: build/pmdsky.us/pmdsky.us.nds: OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 03:51:32 -07:00
cecilarmitais
b6faa49387 Decomp NewWindowScreenCheck, SetScreenWindowsColor and the palette getter
Decompile from asm:

  NewWindowScreenCheck             0x02027648
  GetPaletteBaseAddress__020278A8  0x020278A8
  SetScreenWindowsColor            0x02027A80

NewWindowScreenCheck counts the active windows on each background before
delegating to NewWindow, and sets a flag when either screen has none. It reads
is_active as a signed byte at 0xB6 and bg_id at 0x8, both named by the Window
layout added in the previous commit, so the loop reads as what it does.

It walks with a cursor rather than indexing. Indexing WINDOW_LIST[i] emits an
mla per iteration; the target advances a pointer by 0xE0 at the bottom of the
loop. Its two counters also have to be assigned in the order sub then main --
declaration order alone was not enough, and every permutation of the four locals
left between 20 and 95.

SetScreenWindowsColor's colour parameter is s32, not u8, and that distinction is
not visible in its own bytes: both score 0 against it, because the store is a
strb either way. It is visible one level up. SetBothScreensWindowsColor, landed
matching in the previous commit, passes its argument straight through; a u8
parameter makes the compiler truncate at that call site, which changes an object
that already matched, changes the size of main.sbin, and shifts every overlay
after it. The first build of this batch failed 33 checksums for that reason,
with no compile error and nothing wrong in the function being added.

GetPaletteBaseAddress__020278A8 reads through _020AFC70, which include/
main_02064FFC.h already declares as u8 *. It is declared the same way here
rather than being given a second, differently typed declaration.

No comments are added to any pmd-sky file.

Authored by Claude (Opus 5) under human direction. Confirmed by a matching
build: build/pmdsky.us/pmdsky.us.nds: OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 03:25:19 -07:00