1543 Commits

Author SHA1 Message Date
AnonymousRandomPerson
c313f0090e Merge pull request #297 from darkruss48/main
Some checks failed
build / build (push) Has been cancelled
Decomp 8 functions, emptying seven asm files
2026-09-10 19:26:02 -04:00
darkruss48
a3fef4c1ac Clean up comments in mai_020527A8.c file
comments cleared
2026-09-10 23:44:39 +02:00
darkruss48
4558d17ea1 Clean up comments in sub_0200EB64 function
comments cleared
2026-09-10 23:41:47 +02:00
darkruss48
2c2c5c2a04 Decomp 8 functions, emptying seven asm files
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK.
2026-09-10 21:10:23 +00:00
AnonymousRandomPerson
02e838c934 Merge pull request #296 from AnonymousRandomPerson/main
Some checks failed
build / build (push) Has been cancelled
Synced from pmdsky-debug
2026-09-07 12:34:41 -04:00
AnonymousRandomPerson
db6076849a Rename quicksave symbols according to comments 2026-09-07 00:18:03 -04:00
AnonymousRandomPerson
8a05f6dac5 Synced from pmdsky-debug 2026-09-06 23:42:12 -04:00
AnonymousRandomPerson
f14ee2c91c Merge pull request #292 from SethBarberee/overlay_30
Some checks failed
build / build (push) Has been cancelled
Overlay 30
2026-09-04 23:46:31 -04:00
Seth Barberee
d30c1a4e3d Add initial chars to charmap 2026-09-04 13:13:23 -07:00
Seth Barberee
180541ceb8 finish func decomp of overlay_30 2026-09-04 12:45:57 -07:00
Seth Barberee
97ebe37ae4 more overlay_30 funcs 2026-08-27 08:10:35 -07:00
Seth Barberee
8c39cbea58 more decomp 2026-08-27 08:10:35 -07:00
Seth Barberee
3aa992262a decomp few more saving funcs 2026-08-27 08:10:35 -07:00
Seth Barberee
fcc7009d8b Match few funcs of overlay_30
Thanks to @taxicat for matching ov30_02382874
2026-08-27 08:10:35 -07:00
AnonymousRandomPerson
8588664e24 Merge pull request #295 from AnonymousRandomPerson/main
Some checks failed
build / build (push) Has been cancelled
Add some move effect labels
2026-08-24 22:23:34 -04:00
AnonymousRandomPerson
1527372edd Merge branch 'main' into main 2026-08-24 21:54:22 -04:00
AnonymousRandomPerson
768b41dd19 Add some move effect labels 2026-08-24 21:53:50 -04:00
AnonymousRandomPerson
51c365dbbe Merge pull request #294 from AnonymousRandomPerson/main
Some checks failed
build / build (push) Has been cancelled
Sync some param names with pmdsky-debug
2026-08-23 13:24:16 -04:00
AnonymousRandomPerson
5e0b63660c Fix JP build 2026-08-23 13:05:49 -04:00
AnonymousRandomPerson
cf1fa6f35a Sync some param names with pmdsky-debug 2026-08-23 12:47:25 -04:00
AnonymousRandomPerson
4145bcf47a Merge pull request #293 from AnonymousRandomPerson/main
Some checks failed
build / build (push) Has been cancelled
Synced from pmdsky-debug
2026-08-22 21:03:39 -04:00
AnonymousRandomPerson
f59becd3f6 Synced from pmdsky-debug 2026-08-22 20:45:50 -04:00
AnonymousRandomPerson
440d7b7dcd Merge pull request #291 from CecilArmitais/decomp-continued
Some checks failed
build / build (push) Has been cancelled
Decomp continued
2026-08-21 13:22:34 -04:00
AnonymousRandomPerson
c07a829640 Merge branch 'main' into decomp-continued 2026-08-21 12:54:55 -04:00
cecilarmitais
6425efdd8d Decomp 16 functions, emptying nine asm files
Third cleanup batch. Nine asm/*.s files and their .inc files are removed;
main.lsf drops from 1168 to 1159 objects.

  overlay_29_0234921C  IsCurrentMissionType, IsCurrentMissionTypeExact
  main_02058E8C        DisableAllIqSkills, EnableAllLearnableIqSkills
  main_02058D04        GetLearnableIqSkills
  main_02058C4C        GetUnlockedTactics, GetUnlockedTacticFlags
  main_020307B8        sub_020307B8, sub_020307EC
  overlay_29_02300D50  ov29_02300D50, ov29_02300DC0
  overlay_29_022E28D4  IsValidTargetEntity, CanSeePosition
  main_0206A750        sub_0206A7CC
  overlay_29_022E66D8  ov29_022E66D8, ov29_022E6724

main_0202AAA8.h: the coarse field_0xFC[0x9C] placeholder is split into
field_0xFC[8] / u32 field_0x104 / field_0x108[0x90]. Byte-neutral, and
nothing in the tree referenced the placeholder by name.

Two pre-existing declarations of landed functions are replaced with an
include of the header that now declares them. dungeon_recruitment.c
declared IsCurrentMissionTypeExact as (u32, u32) where it takes
(enum mission_type, u8); both call sites pass enum constants, so the ROM
is unchanged.

TACTICS_UNLOCK_LEVEL_TABLE, sub_02032984 and sub_0204E6FC/0204E770/
0204E780 are declared provisionally at the call site; no header declares
them yet.

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-21 01:41:15 -07:00
cecilarmitais
d9df74f0f6 Decomp 17 functions, emptying eight asm files
Second cleanup batch. Eight files are now gone:

  asm/overlay_29_022E1618.s   asm/main_0202B530.s
  asm/overlay_29_022DC65C.s   asm/main_0205EC38.s
  asm/overlay_29_0232124C.s   asm/main_02051788.s
  asm/main_02042B20.s         asm/main_02065BD8.s

main.lsf falls from 1175 objects to 1167.

Twenty-two functions matched across eleven files, but only seventeen land.
FixedPoint64ToInt, GetSpriteSize and RemoveItemFromKecleonShop1 did not match,
and their files therefore cannot be emptied; landing their already-matched
siblings would have converted two two-function files into two fresh
single-function fragments, so those two are held back as well. This batch
reduces the fragment count without creating any.

Three declarations follow the tree rather than the scratch: ov29_0232119C takes
struct entity * as its first parameter, ov29_023538B4 is already declared as a
u8 array, and ov29_022DC2B8 and ov29_022DC33C are declared u8 * in their
destination file. That last one is inconsistent with poly_text.h, which declares
ov29_022DC2B8 as struct unk_ov29_022DC240_t *; the file already carried the same
split for ov29_022DC240, so its local convention was followed rather than
changing pre-existing code. Worth unifying separately.

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-21 00:56:33 -07:00
cecilarmitais
be41c2f3d5 Decomp 20 functions, emptying six asm fragments
First cleanup batch. All twenty matched at score 0, and every file they came
from is now gone:

  asm/main_0204F9F4.s         2 functions
  asm/main_02017C50.s         4
  asm/overlay_29_02344B44.s   2
  asm/overlay_11_0230CCE0.s   2
  asm/overlay_11_022E9D6C.s   5
  asm/main_0201BEB0.s         5

main.lsf drops from 1181 objects to 1175, the first net reduction on this
branch. Each removal also retires the matching asm/include/*.inc.

Most of these reuse types landed earlier and add nothing: the OAM group reuses
unk_0201BCCC with unk_oam_sub and unk_oam_elem, and the overlay_11 fade group
reuses unk_023890A0 and unk_0238916C. Only unk_0238A098 and unk_023531A4 are
new.

Note for later cleanup work: six of the twenty are the last function in their
file, so emptying it leaves them with no following address and the object-level
size check cannot cover them. On a cleanup batch the matching build carries
more of the verification than usual.

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-21 00:32:47 -07:00
cecilarmitais
f968c89066 Decomp 48 functions in five groups
Ninth 5x10 batch; 48 of 50 matched at score 0 and land here.

  overlay_11_022FD308  LivePerformer accessors
  main_0204CF9C        GLOBAL_PROGRESS_PTR bit-array accessors
  main_020022C4        string, thread and card initialisation
  overlay_11_022E9D6C  screen-fade queries
  main_0203C774        state-machine steps

New placeholder structs: unk_022FE490, unk_022FE498, unk_020AFE60, unk_020AFE70,
unk_0209C7F4, unk_0238916C, unk_0229B004, unk_0229AFC0. The overlay_11 fade
group reuses unk_02388FC0 and unk_023890A0 unchanged.

Two are NOT here. SetPositionInitialLivePerformer sits at 225, where an
address computation is scheduled earlier than the target places it; six
variants moved nothing. sub_020024E4 sits at 35, a two-register swap in a
zero-fill loop, after both declaration orderings, a block scope, an extra
temporary and a while form. Both stay as assembly.

Matching finding, now in docs/MATCHING_TIPS.md: a two-word struct copy emits
the same four instructions as two field assignments but schedules both loads
first, which is what the target has. Writing the fields separately interleaves
load and store, and hoisting them into locals merges the stores into an stm.

The OS wrappers drop their local declarations of nitro functions, which reach
every translation unit through the prefix header and disagreed on return type.
OS_ResetSystem keeps its extern; it is declared in no reachable header.

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-21 00:13:12 -07:00
cecilarmitais
c61f8ec2d7 Decomp 49 functions in five groups
Eighth 5x10 batch; 49 of 50 matched at score 0 and land here.

  overlay_11_022FAC54  LiveObject accessors
  overlay_11_022E46FC  coroutine table and special recruitment
  main_020325AC        further inventory-menu paging
  overlay_17_0238A754  menu state setters
  main_0201BAC8        OAM attribute copying

New placeholder structs: unk_022FD1A0, unk_02324FA0, unk_02320904,
unk_C_ROUTINES, unk_0238BE00, unk_0201BCCC with unk_oam_sub and unk_oam_elem.
struct unk_020332AC gains field_0xBC and field_0xD0, splitting two byte arrays
without changing its size; no already-landed function changes.

GetCoroutineInfo is NOT here. It reaches 30 -- two rows, a register swap between
the base pointer and the record pointer, with every instruction otherwise
identical. Eight structural variants and six declaration orderings were tried;
restructuring around a record pointer took it from 500 to 30 and nothing since
has moved it. It stays as assembly.

Two matching findings, both in docs/MATCHING_TIPS.md. A switch needs a fourth
case before MWCC emits a binary split rather than a flat compare chain, which is
now the second batch where that closed a function. And x == 4 || x == 5 folds
into a range test at every width tried, where the target keeps cmp/cmpne; the
double negation !(x != 4 && x != 5) blocks the fold and keeps the arm order.

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-20 23:04:46 -07:00
cecilarmitais
e6530b4337 Decomp 50 functions in five groups
Seventh 5x10 batch; all fifty matched at score 0.

  overlay_11_022EE5E4  LiveActor accessors
  overlay_11           language and string helpers
  main_020325AC        inventory-menu paging and scaling
  overlay_29_0234B4CC  alert-box wait, portrait init, message log
  overlay_18           further LINK_SHOP_PTR setters

New placeholder structs: unk_022FAB44, unk_020332AC, unk_0234BAC0. struct
unk_0238C950 gains an s8 at offset 4, splitting its leading byte array without
changing its size; no already-landed function changes. struct unk_023537CC is
copied from the neighbouring sources that already define it, and struct iovec
now comes from file.h rather than a local copy.

Seven callees were already declared elsewhere in src/ and are reused verbatim
rather than redeclared: AdvanceFrame, DUNGEON_BUTTON_INPUT, MESSAGE_LOG_INFO,
GetSimpleMenuResult__0202B870, GetLanguage, LoadFileFromRom and
UnkMapRelatedFunc.

docs/MATCHING_TIPS.md gains three entries: a case label sharing default's body
still shapes the compare chain; a masked value promotes to int, so an unsigned
compare needs a cast; and the two malformed disassembly shapes, with the
reachability test that separates a merged block from an ordinary loop.

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-20 15:28:55 -07:00
cecilarmitais
090d9f3159 Decomp 50 functions in five groups
Sixth 5x10 batch; all fifty matched at score 0 and landed.

  overlay_29_022DC694  HEAD  team-stats forwarders, a 10-argument forwarder,
                             and a 22-entry table search
  overlay_29_022E4714  HEAD  PlayEffectAnimationEntity wrappers
  overlay_29_022E37DC  TAIL  same family, merging into overlay_29_022E406C.c
  overlay_18           mid   LINK_SHOP_PTR state setters
  main_020022C4        mid   Nitro OS thread and mutex wrappers

New placeholder structs: unk_022DC694, unk_02353518, unk_0238C950,
unk_020027E8, unk_0229B0E0. The OS wrappers use nitro's own OSThread and
OSMutex types, which every translation unit already has through the prefix
header, rather than private tags.

Two spellings a reviewer should weigh, both recorded in the note:
_0229B0E0 is declared volatile because the target reloads it where any
ordinary spelling is common-subexpression-eliminated, and ov29_022DC78C
matches in byte-offset form rather than array indexing because the target
keeps the offset live in a separate mul.

Group selection now rejects malformed disassembly: 0.4% of asm blocks end
without a return (a .global mid-body split one function in two) and 6.5% are
several functions merged into one block (no .global marks the later entry
points). Neither is decompilable as written.

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-20 15:09:01 -07:00
cecilarmitais
1dea0a2571 Decomp 10 DWC functions into lib/src; they need the SDK build rule
The group from asm/overlay_00_022DB1A4.s that the previous commit could not
land. It does not belong in src/: these are Nintendo Wi-Fi Connection library
functions, and src/** is built with OPTFLAGS -O4,s, which inlines a small callee
whose body is visible in the same translation unit. lib/** is built with
OPTFLAGS_SDK -O4,p, which does not. Landed into lib/src/overlay_00_022DB1A4.c
and listed in main.lsf under OVY_0, all ten are byte-identical to the original
assembly.

A decomp.me scratch cannot see this: it declares every callee extern, so no body
is visible and nothing can be inlined, and the group scored 0 either way.

lib/src was already in LIB_SRC_SUBDIR without existing on disk, so no makefile
change is needed. The object also receives the full defines, not just
GLB_DEFINES; none of these functions carries a region conditional in any case.

docs/MATCHING_TIPS.md carries the mechanism, a minimal reproducer, and a
one-object diagnostic that does not need a full build.

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-20 14:15:03 -07:00
cecilarmitais
c9d0c76608 Decomp 38 functions across four groups; drop a group to an inlining trap
Fifth 5x10 batch. 48 functions matched at score 0; 38 land here.

  overlay_29_022E37DC  -> src/overlay_29_022E406C.c   (new, 10)
  overlay_29_022E41F0  -> src/overlay_29_022E4338.c   (new, 10)
  overlay_11_022E9B84  -> src/overlay_11_022E9A78.c   (merged, 10)
  main_02048764        -> src/main_02048B48.c,
                          src/main_02048BB4.c,
                          src/main_02048CB8.c         (new, 8)

New placeholder structs: unk_020AFF38, unk_022AAE74. Two existing placeholders
in overlay_11_022E9A78.h are refined by this batch's evidence -- u8 field_0x4[8]
becomes s32 field_0x4 + s32 field_0x8, and u8 field_0x0[0x44] gains s16
field_0x14. Both keep their total size and no pre-existing function changed.
overlay_29_022E406C.h and overlay_29_022E4338.h gain dungeon_mode.h, which they
need for struct entity.

The fifth group -- ten DWC functions from asm/overlay_00_022DB1A4.s -- is not
here. All ten scored 0 and still changed OVY_0's size by 16 bytes, failing
main.sbin and OVY_0-OVY_9. A decomp.me scratch declares callees extern, so MWCC
cannot inline them; landing the group into a .c that defines those callees makes
the bodies visible and -O4,s inlines them. The target's calls show retail kept
these in separate translation units. docs/MATCHING_TIPS.md gains an entry with
the mechanism and a one-object diagnostic that does not need a full build.

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-20 03:18:59 -07:00
cecilarmitais
f85044d37f Drop 49 unneeded util.h includes from generated headers
The landing script added `#include "util.h"` to every header it generated,
across this whole branch. That was never necessary for most of them: u8/u32/s32
and the rest of the base types are typedef'd in lib/include/nitro/types.h, which
every translation unit already has through `-prefix global.mch`. 283 of the 460
headers in the tree that name u32 do not include util.h and build fine.

util.h owns bool8, bool32, fx32_8, ufx32_8 and struct fixed_point/rgba/vec2_16 --
a header naming any of those genuinely needs it, and 61 of the 110 do. The other
49 carried it for nothing and are cleaned up here.

Removal is .c-aware: util.h is kept wherever the header's paired source names a
util.h-owned symbol and does not include util.h itself, so nothing loses it
transitively. No functional change; verified byte-identical.

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-20 01:30:22 -07:00
cecilarmitais
a6ce70e56b Decomp 50 functions in five themed groups
Fourth 5x10 batch.

  overlay-11 shop/menu loaders      10   LoadCroagunkSwapShopOverlay .. ov11_0230CE1C
  animation-table getters           10   ov10_022BFE54 .. ov10_022BFF30
  move-animation flag readers       10   ov10_022BFD58 .. ov10_022BFE3C
  overlay_01 menu accessors         10   ov01_0233755C .. ov01_02337624
  sound veneers + playing checks     10   sub_02017B70 .. IsMePlaying

None carries a region conditional -- checked per function, not per file -- so US
alone verifies this commit. Four destination files, one .s split in total.

A bitfield read is not the same as the equivalent shift expression. Dwci_Entry-
style `(x << 28) >> 28` is folded by MWCC into `and #0xF`, while the target keeps
both shifts; declaring the member `u32 f : 4` emits them. That finding came from
the overlay_02 group, which is NOT in this commit -- see below.

GetMoveAnimation returns a 0x18-byte element of MOVE_ANIMATION_INFO. The five
flag readers in the third group index field_0x8 of that same element, so both
groups share one struct move_anim_info rather than the placeholder the flag
readers were first written against; all seven were re-scored against the unified
type.

ov10_022BFE6C needs `if (cond) { ...; return TRUE; } return FALSE;` -- the
inverted arrangement predicates the pointer load instead of branching (1100).

A sixth group of ten (Dwci_ChangeScene .. Dwci_Language__02339674, overlay_02)
matched at score 0 and is NOT landed. Extracting from asm/overlay_02.s breaks
OVY_2's checksum on its own: bisecting to a single three-instruction function
still fails, so the C is not implicated. Splitting that file also leaves four
symbols (SoAlloc, SoFree, ov02_0232FD28, ov02_0232FD40) undeclared in the tail,
which the stock extract_function.py does not carry across. Left for a separate
investigation.

Authored by Claude (Opus 5) under human direction. All fifty verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 01:07:35 -07:00
cecilarmitais
c34d1196f2 Decomp 50 functions in five themed groups
Third 5x10 batch: fifty located as five groups of ten before any matching, all
fifty matched, one build, one commit.

  Dwci account bitfield accessors   10   Dwci_Acc_SetMaskBits .. Dwci_Acc_GetFlags
  overlay-11 menu/overlay loaders   10   ov11_0230CB88 .. LoadRecycleShopOverlayResume
  _020B0B6C accessors + copies      10   sub_0206C0D8 .. sub_0206C19C
  overlay-11 veneers                10   ov11_022E9A78 .. ov11_022E9B5C
  main_02065C84 wrappers            10   sub_020663C8 .. sub_020664AC

Each group is a contiguous run, costing one .s split apiece. None of the fifty
carries a region conditional -- checked per function, not per file -- so US alone
verifies this commit.

The two 8-byte copy loops need an UNSIGNED counter. With s32, `--n != 0` emits
sub followed by cmp and scores 505; with u32 it fuses into the target's single
subs. A struct assignment through a cast also scores 0 but needs a new type.

ov11_0230CB88 passes an argument to EntryOverlay13, which this tree already has
decompiled and matching as `void EntryOverlay13(void)`. Dropping the argument
scores 220 -- the target saves r0 into r4 across the InitMenu call specifically
to pass it. Retail's caller evidently had a prototype its definition did not
match; reproducing that needs the two declarations to disagree across translation
units, so this file declares `extern void EntryOverlay13(s32 a);` locally.

Dwci_Acc_GetUserId and Dwci_Acc_GetFriendKey return 64-bit values; the tell is
the pair of no-op `orr rX, rX, #0` instructions MWCC emits assembling a u64
across r0/r1. GetUserId's high half is field_0x0 masked to 0x7FF, which agrees
with Dwci_Acc_SetUserId passing that same mask to Dwci_Acc_SetMaskBits.

New placeholder structs: unk_022DB0E0, unk_020B0B70, unk_02388FC0, unk_023890A0.

Authored by Claude (Opus 5) under human direction. All fifty verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 00:11:24 -07:00
cecilarmitais
e865b69791 Decomp 49 functions in five themed groups
Second 5x10 batch: located as five groups of ten before any matching, then all
matched, then one build, then one commit.

  inventory menu window accessors    10   ov10_022BCC7C .. ov10_022BCDBC
  file/ROM transfer + bag init       10   FileRom_StopDataTransfer .. sub_0200CAE4
  overlay_16 + secret bazaar         10   ov16_0238CC94 .. TalkToSecretBazaarNpcWithYesNoMenu
  Gt2 socket/connection accessors    10   Gt2GetConnectionState .. Gt2SetConnectionData
  forwarding veneers at +4            9   sub_0202613C .. sub_020261E4

Each group is a contiguous run, which costs one .s split apiece rather than one
per function: after the first extraction the next function is at the head of the
remainder and merges into the source just created. None of the 49 carries a
region conditional -- checked per function, not per file -- so US alone verifies.

GetDamageSource returns s16. The lsl #16 / asr #16 before its return is the
return conversion, not a cast in the body; s16 return with an s32 parameter
scores 0, while returning s32 and casting scores 510 in the shape the target
does not use.

ov29_022F05B4 needed its two arms in the other source order -- the fourth
instance of MWCC letting the first arm written fall through.

TalkToSecretBazaarNpcStandard and ov29_022F0618 differ only by `mov r3, #0`
versus `mov ip, #0`. r3 is the fourth argument register: the Standard variant
passes 0 for it, the other forwards its own. Same callee, different arity.

IsInventoryMenuActive returns s32, not bool8 -- bool8 adds an and #0xff the
target lacks.

struct unk_0202AAA8's field_0xA4[0xF4] is split to expose field_0xF8. New
placeholder structs: unk_020AF360, unk_0238CE40, unk_02026130, unk_0230E3E8 and
unk_0230E420 (the Gt2 connection and socket are distinct types -- remote IP sits
at offset 0, local IP at 4).

A fiftieth was prepared and not landed: sub_0202614C stands at 300. The target
materialises &v into r3 before the first store and moves it to r1; six spellings
(struct by value, a pointer local, storing through the pointer, an array, a
reversed store order, a hoisted destination) all compute the address after the
stores instead.

Authored by Claude (Opus 5) under human direction. All 49 verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 23:42:03 -07:00
cecilarmitais
7658e4f92e Decomp 50 functions in five themed groups
Located as five groups of ten before any matching was attempted, then all fifty
matched, then one build, then one commit.

  overlay_04/06 global accessors           10   ov04_0233CA80 .. ov06_0233CAA8
  hardware register bit-fields             10   sub_02009BE8 .. sub_02009D20
  save reset / play timer                  10   sub_020483B8 .. sub_0204F9E0
  sound veneers + window accessors         10   sub_02017C90 .. sub_02030A74
  dungeon fixed-room / item                10   CloseFixedBin .. GenerateStandardItem

Every group is a contiguous run at a file head or tail, so extract_function
merges each function into an adjacent source instead of splitting a .s. None of
the fifty carries a region conditional -- checked per function, not per file --
so US alone verifies this commit.

Twelve of the fifty are interworking tail-call veneers (ldr ip, =f; bx ip). That
falls straight out of an ordinary forwarding call, and survives both argument
reordering (GenerateStandardItem) and a computed argument (sub_020483B8).
Nothing in the tree had a veneer decompiled, so the shape was proven on one
before the other forty-nine were written. Their parameter lists are guesses: a
veneer forwards registers untouched, so the emitted code is identical for any
arity and the match constrains nothing.

sub_020483D8 returns its callee's result. It sat at 40 through five spellings
with the pointer one register low; the target never reuses r0 after the call
because that value is the return value. Adding `return ok;` gives 0, and the
return is invisible in the asm because the value is already in place.

Two type corrections found by probing: the Are*Allowed family compares the
dungeon id unsigned (bcc, not blt -- 200 signed), and the register setters need a
u32 intermediate, since a u16 local forces a lsl/lsr truncation the target lacks
(615).

New placeholder structs: unk_0233F660, unk_0233EEE0, unk_020AFEF4, unk_02030A50.
src/main_02017C80.c's existing PlaySeByIdVolume(s32, s32) declaration is kept in
preference to this commit's; both affected functions were re-scored against it
and still match.

Authored by Claude (Opus 5) under human direction. All fifty verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 23:18:03 -07:00
AnonymousRandomPerson
da4f51d429 Merge pull request #290 from CecilArmitais/decomp-continued
Some checks failed
build / build (push) Has been cancelled
Decomp continued
2026-08-20 02:02:37 -04:00
cecilarmitais
5ffad87a1b Decomp five leftover single-function asm files
Eleventh cleanup sweep. Five asm files and their includes removed:

  asm/main_0205B6CC.s         sub_0205B6CC
  asm/main_0202C75C.s         sub_0202C75C
  asm/overlay_29_0232CDA4.s   DoMoveOneShot
  asm/overlay_29_0232A078.s   DoMoveNightShade
  asm/overlay_29_023016D8.s   DisplayRunAwayIfTriggered

All five merged into an adjacent source rather than splitting one. None carries
a region conditional, so US alone verifies this commit.

sub_0205B6CC is a 64-bit unsigned >= 2 (cmp/cmpeq/movhs) on a value at offset
0xC. A u64 member sits there: MWCC aligns long long to 4, not 8. Rebuilding the
value from two u32s scores 200, and `> 1` in place of `>= 2` scores 310.

sub_0202C75C uses struct unk_0202C5E0, the collection-menu window struct its
neighbours already use; GetWindowIdSelectedMenuItemIdx immediately before it
already spells the same `GetWindowContents(window_id) + 4`. field_0x1AC[6]
covered 0x1B0/0x1B1 and is split into three members.

DoMoveOneShot and DoMoveNightShade are twins staging eleven arguments for
CalcDamageFixedWrapper, which had no declaration in the tree. The only obstacle
was the temporary holding GetMoveType's result: as enum type_id, -enum min sizes
it to a byte and emits an and #0xff the target lacks (950); as s32, 0.

DisplayRunAwayIfTriggered needs Min(999, max_hp), not Min(max_hp, 999) -- Min is
a static inline, so the argument order is not free (200). That exact expression
in that exact order already sat in the NONMATCHING block of AiMovement in
dungeon_ai_movement.c; the guess was right and had never been confirmed.

include/main_02042AF8.h's provisional `s32 sub_0202C75C(s8 a);` is retired in
favour of the real header. It was written from the one call site, which passes an
s8 field; the parameter is a window id.

A sixth was prepared and not landed: FixedPoint64ToInt (asm/main_02001CB0.s)
stands at 225. The target keeps an arithmetically redundant & 0xFFFF0000, and
whether MWCC folds it away is decided by which side of the | the masked term is
written on -- masked second folds it (735), masked first keeps it (225). Writing
it first is also what makes it evaluate first, and the target needs it preserved
but evaluated second; ten spellings found none that does both. Spelling it as a
real 64-bit shift scores 1020.

Authored by Claude (Opus 5) under human direction. All five verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 22:25:23 -07:00
cecilarmitais
159235da43 Decomp five leftover single-function asm files
Tenth cleanup sweep. Five asm files and their includes removed:

  asm/overlay_29_0232CE7C.s   DoMoveReviver
  asm/overlay_29_02327940.s   DoMoveRapidSpin
  asm/overlay_29_022EFA74.s   TryActivateIqBooster
  asm/main_02027AA0.s         sub_02027AA0
  asm/main_020568DC.s         sub_020568DC

All five merged into an adjacent source rather than splitting one. Four of the
five carry a region conditional, so all three ROMs were built; sub_020568DC is
the exception and US alone would have covered it.

TryActivateIqBooster sat at 60 with r6/r7/r8 rotated one place and every
differing row an r-marked register swap. Moving the IQ local's declaration ahead
of the other two takes it to 0. This contradicts the MATCHING_TIPS entry claiming
declaration order never moves callee-saved assignment; that measurement was on
SetLeaderAction's ~75 locals, where register pressure decides the colouring. On
four locals with no pressure, first-definition order is what is left.

DoMoveRapidSpin sets its return to 1 before the random-outcome call, so a failed
random check still returns TRUE. The early-return spelling scores 570; a result
variable set inside the damage branch scores 0.

sub_02027AA0's region difference is not an offset shift: JP writes slot 3 where
the others write slot 0 and vice versa, mirrored for the second case. The rodata
a few symbols away corroborates it -- _020AFD94 and _020AFD98 are defined in
swapped order under the same #ifdef.

sub_020568DC follows GetAppointedLeaderMemberIdx, which lives in the file it
merged into and is the same function specialised to the active team. The
(&t->number_active_team_members_main)[team] idiom is already used by three
existing files.

DoMoveReviver was on the stalled list from 4d2a484c but had never been attempted;
it was set aside for needing region-conditional C, which is one #define.
sub_020568DC and TryActivateIqBooster were likewise untried rather than stuck.

Authored by Claude (Opus 5) under human direction. All five verified at score 0.
Confirmed by matching builds of all three ROMs: US, EU and JP.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 22:03:07 -07:00
cecilarmitais
19c62d4b1f Decomp five leftover single-function asm files; fix three stale declarations
Ninth cleanup sweep. Five asm files and their includes removed:

  asm/overlay_29_0231E990.s   ShouldTryEatItem
  asm/overlay_29_0232D378.s   DoMoveGuardSwap
  asm/overlay_29_0232A490.s   DoMoveSwallow
  asm/overlay_29_02329674.s   DoMoveHelpingHand
  asm/main_0205B738.s         sub_0205B738

All five merged into an adjacent source rather than splitting one.

Three declarations the tree already carried are contradicted by these bytes and
are corrected here, touching five files this sweep did not otherwise decompile:

SubstitutePlaceholderStringTags took `u8 *string_id` in four files and `int a` in
a fifth. DoMoveGuardSwap passes a literal 1, which no pointer parameter can take
without a cast; the existing call sites all passed 0, which is why nothing caught
it. The four are now s32, agreeing with the one that was already an integer.

TryIncreaseHp took `s16 hp` in two files. DoMoveSwallow loads its argument from a
word array and passes it untouched -- s16 inserts a sign extension and scores
210, s32 scores 0. The two existing call sites load s16 data with ldrsh, so the
value is already extended and the wider declaration is byte-neutral for them.

ShouldTryEatItem's parameter is signed: the range check emits blt/ble, while
enum item_id under -enum min compares unsigned and scores 400. s16 matches the
adjacent IsItemValidVeneer and every caller's ldrsh.

DoMoveSwallow also needed its two arms in the other source order, the same rule
as sub_02009DCC last sweep: MWCC lets the first arm written fall through.

sub_0205B738's copy at +0xB0 is element [1] of struct0, not a member: 0xB0 is
sizeof(struct unkStruct_020B0A54), as sub_0205B77C (a * 176 + ...) and
sub_0205B7C8 (MemsetSimple(..., 0xB0)) already say. Reading it as a member and
appending one scored 0 on a scratch but changed the struct's size, and with it
the stride in three neighbours and the copy length in a fourth -- 29 binaries
moved. No header change is needed; the array spelling also scores 0.

Three of the five log a message whose id differs between US and JP by no constant
offset, so each is a file-scope #ifdef JAPAN define, as dungeon_ai.c and
dungeon_projectile_throw.c already do.

Authored by Claude (Opus 5) under human direction. All five verified at score 0.
Three carry region conditionals, so this was confirmed by matching builds of all
three ROMs: US, EU and JP.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 21:36:48 -07:00
cecilarmitais
8cfb04e1a4 Decomp five leftover single-function asm files
Eighth cleanup sweep. Five asm files and their includes removed:

  asm/overlay_29_0230F840.s   TeamMemberHasExclusiveItemEffectActive
  asm/overlay_29_023276E8.s   DoMoveTickle
  asm/overlay_29_0232C538.s   DoMoveSwitchPositions
  asm/overlay_29_022FF8C8.s   GetMobilityTypeAfterIqSkills
  asm/overlay_29_0233861C.s   UpdateShouldBoostHiddenStairsSpawnChance

All five merged into an adjacent source rather than splitting one.

DoMoveTickle was the stall recorded on 78b52f9d at score 15. The target reaches
ATK_STAT_IDX through SPATK_STAT_IDX's pool entry at offset 4, which is what the
two symbols' adjacency in rodata makes them. Declaring SPATK_STAT_IDX with array
type and indexing [1] emits that; taking the address of a scalar declaration and
indexing does not. DoMoveMetalSound, which shares the file, moves to
SPATK_STAT_IDX[0] for the same declaration.

TeamMemberHasExclusiveItemEffectActive replaces the provisional
`bool8 TeamMemberHasExclusiveItemEffectActive(u8);` that src/overlay_29_02338548.c
declared from its call site. The parameter is enum exclusive_item_effect_id --
u8 scores 0 in isolation but the build's -W error rejects the implicit conversion
at the inner call to ExclusiveItemEffectIsActive__0230F8AC. Both call sites move
from 0x5e/0x5f to EXCLUSIVE_EFF_MORE_KECLEON_SHOPS/EXCLUSIVE_EFF_MORE_HIDDEN_STAIRS.

DoMoveSwitchPositions raises exp_yield to 1 when below it; spelled `== 0` rather
than `< 1` it scores 405.

GetMobilityTypeAfterIqSkills is a whole function inside #ifndef JAPAN, so the
guard moves into the .c and around the prototype in the .h.

Authored by Claude (Opus 5) under human direction. All five verified at score 0.
Three carry region conditionals, so this was confirmed by matching builds of all
three ROMs: US, EU and JP.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 21:09:44 -07:00
cecilarmitais
4d2a484c28 Decomp five leftover single-function asm files
Seventh cleanup sweep. Five asm files and their includes removed:

  asm/overlay_29_0232E400.s   DoMoveWakeUpSlap
  asm/main_0204317C.s         FreeUnkStorageStruct0x18c0
  asm/main_02009DCC.s         sub_02009DCC
  asm/main_020018A4.s         sub_020018A4
  asm/main_0200C4CC.s         sub_0200C4CC

All five merged into an adjacent source rather than splitting one, so the sweep
removes five files and adds none.

DoMoveWakeUpSlap doubles the damage multiplier when the target is in any of the
three sleep-class states, then ends the status. EndSleepClassStatus takes five
arguments here, not four: the target loads r2=0, r3=1 and pushes a third flag on
the stack.

sub_020018A4 rounds a 64-bit value up to the next multiple of 0x100 and returns
the high 56 bits. The `and r2, r1, #0` that opens it is the high half of a 64-bit
`x & 0xFF`, not a separate test.

sub_02009DCC clears one bit of a 5-bit mask per non-zero entry in five byte
arrays at stride 5, then merges it into DISPCNT for the requested engine. The
zero-engine arm has to come first in the source or the wrong arm is predicated.

sub_0200C4CC copies 232 bytes out of _02094C18, whose size is fixed by the gap to
_02094D00.

Field types forced by the access widths in main_02042AF8.h: struct unk_02043148's
field_0x0 becomes s32 and field_0x7D5 splits into two s8s plus padding; struct
unk_020AFEE0's field_0xC becomes s32, which was the last differing row in
FreeUnkStorageStruct0x18c0.

struct unk_02094C18 is new. Its member is u32[0x3A] rather than u8[0xE8] because
the copy's alignment, and so its instruction shape, comes from the member type.

Authored by Claude (Opus 5) under human direction. All five verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. None carries a
region conditional, so US alone is sufficient.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:30:00 -07:00
cecilarmitais
658a92a802 Decomp four leftover single-function asm files
Sixth cleanup sweep. Four asm files and their includes removed:

  asm/overlay_29_02328A74.s   DoMoveDamagePoison40
  asm/overlay_29_02329FE0.s   DoMoveMudSlap
  asm/overlay_29_0232B820.s   DoMoveMistBall
  asm/main_0200F18C.s         GetEquivItemIndex

The three move effects share DoMoveBubble's shape: deal damage, and on a random
outcome apply a secondary effect, returning whether damage landed rather than
whether the effect did. The result variable doubles as an argument in two of
them -- MistBall passes it as both the stage count and the checkProtected flag,
MudSlap passes 0 as the chance.

GetEquivItemIndex walks the 50 bag slots with a cursor, testing each item's
exists flag as `(flags & 1) != 0` so the boolify emits tst/movne/moveq, and
returns the index of the first equivalent item or -1.

A fifth was prepared and not landed: GetNextIqSkill (asm/main_02058F24.s) sits at
30, the whole difference being that the target keeps its skill-list cursor in lr
where the candidate uses r5. Four spellings tried -- hoisting the value local,
moving the cursor declaration, a group temporary, and a while loop -- all 30 or
worse.

Authored by Claude (Opus 5) under human direction. All four verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. None carries a
region conditional, so US alone is sufficient.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:03:40 -07:00
cecilarmitais
78b52f9d63 Decomp five more leftover single-function asm files
Fifth cleanup sweep; five more asm files and their includes removed:

  asm/overlay_29_023491C4.s   IsOutlawOrChallengeRequestFloor
  asm/main_0202AAE8.s         sub_0202AAE8
  asm/main_0202BC60.s         sub_0202BC60
  asm/overlay_29_023261A0.s   DoMoveBubble
  asm/main_0205BCC4.s         sub_0205BCC4

sub_0202AAE8 and sub_0202BC60 are the same function over different window
states: check unk_0202AAA8::field_0x19C against a set, then set two flags, clear
field_0x1A4, call sub_0202830C with -5 and advance the state. Both write a byte
at 0x1A1 that the struct covered only as padding after field_0x1A0, so that gap
is now named field_0x1A1 with field_0x1A2[2] holding the remainder -- same total
size.

Three spellings that mattered:

- IsOutlawOrChallengeRequestFloor is three ORed predicates and only matches with
  each operand written `!= 0`; a plain || scores 300 and early returns 1300.
- DoMoveBubble returns whether damage was dealt, not whether the speed drop
  landed, so the result is funnelled through one variable which is also passed
  as LowerSpeed's stage count.
- sub_0205BCC4 must not hoist the destination pointer above its NULL check; a
  local shared by both branches scores 830, one declared inside the else branch
  matches.

Authored by Claude (Opus 5) under human direction. All five verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. None carries a
region conditional, so US alone is sufficient.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:52:00 -07:00
cecilarmitais
901ba2aa8f Decomp five more leftover single-function asm files
Fourth cleanup sweep; five more asm files and their includes removed:

  asm/overlay_29_0232B8E4.s   DoMoveCalmMind
  asm/overlay_29_0232D22C.s   DoMoveHammerArm
  asm/overlay_29_023495E8.s   IsDestinationFloorWithFleeingOutlaw
  asm/overlay_29_023492D4.s   IsLegendaryChallengeFloor
  asm/main_02030850.s         CloseAdvancedTextBox2

The two mission predicates merged into files that already declared
IsCurrentMissionType and IsCurrentMissionTypeExact with enum mission_type
parameters, so they use those declarations and the MISSION_* enumerators rather
than fresh externs with integer types. IsLegendaryChallengeFloor's floor check
is a byte subtraction written `+ 0xFF`, the same encoding DoMoveGust needed.

Both predicates only match written as a nested `if` that falls through to a
single return; the early-return spellings score 610 and 405.

CloseAdvancedTextBox2 uses the existing sub_0202836C, sub_0202812C, DeleteWindow
and MemFree declarations; only sub_020288DC needed a provisional extern.

Authored by Claude (Opus 5) under human direction. All five verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. None carries a
region conditional, so US alone is sufficient.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:37:38 -07:00
cecilarmitais
0587a6efcb Correct SetActionUseMovePlayer's parameter types; retire the last stale extern
The previous commit left src/overlay_29_022F0EDC.c carrying a provisional
`extern s32 SetActionUseMovePlayer();` because replacing it with the real header
broke three modules. The cause was not the return type, which is void, but the
parameters: the function was landed as (struct action_data*, u8, u8), and a u8
parameter makes every caller truncate.

SetLeaderAction's call site in retail passes GetTeamMemberIndex's result
unchanged and sign-extends the move index to 16 bits:

    mov r1, r0
    mov r2, r4, lsl #0x10
    mov r2, r2, asr #0x10
    bl SetActionUseMovePlayer

so the parameters are s32 and s16. The callee's own body cannot distinguish
u8, s16 or s32 -- it stores both with strb, and all three score 0 against it --
which is why the wrong types went unnoticed when it was landed.

With (struct action_data*, s32, s16) both functions match and the provisional
extern is deleted in favour of the header, leaving one declaration in the tree.

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-19 18:44:59 -07:00
cecilarmitais
ec25edd9dd Decomp five more leftover single-function asm files
Third cleanup sweep; five more asm files and their includes removed:

  asm/overlay_29_023021F0.s   UpdateIqSkillsWrapper
  asm/overlay_29_022EBC98.s   SetActionUseMovePlayer
  asm/overlay_29_02349658.s   ov29_02349658
  asm/main_0205EBF0.s         sub_0205EBF0
  asm/overlay_29_022F52B0.s   ov29_022F52B0

SetActionUseMovePlayer sets ACTION_USE_MOVE_PLAYER and then two
action_parameters[].action_use_idx fields, using the enumerator and struct that
already exist. sub_0205EBF0 indexes mission_deliver_list::unk18, the struct
src/main_0205C73C.c already uses, rather than a fresh placeholder.

NOT done, deliberately: src/overlay_29_022F0EDC.c still carries the provisional
`extern s32 SetActionUseMovePlayer();`. Replacing it with an include of the real
header, which declares the function void, breaks the ROM -- SetLeaderAction's
match depends on the s32 form. The two declarations therefore still disagree.
That is a real defect in one of the two, not a formality, and it is left alone
rather than papered over; see the reasoning note.

ov29_022F52B0 is a bare veneer with no argument setup, so its arity is not
evidenced by anything and void(void) is a guess.

Authored by Claude (Opus 5) under human direction. All five verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. None carries a
region conditional, so US alone is sufficient.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 18:33:53 -07:00
cecilarmitais
80d0e710e0 Decomp five more leftover single-function asm files
Second cleanup sweep. Each was the only function left in its own asm file, so
each removes an asm file and its include:

  asm/overlay_29_0234B0CC.s   SetMessageLogPreprocessorArgsStringToName
  asm/overlay_29_023268CC.s   DoMoveSmokescreen
  asm/overlay_29_02325F74.s   DoMoveMorningSun
  asm/overlay_29_02326E20.s   DoMoveGust
  asm/overlay_29_022EA980.s   GenerateDungeonRngSeed

Two needed a second reading:

- DoMoveGust doubles the damage multiplier when the defender's
  bide_class_status.bide is 7 or 8. The target tests it as a byte with
  `add #0xF9`, so the source adds 0xF9 rather than subtracting 7; `- 7` compiles
  to `sub #7` and does not match.
- GenerateDungeonRngSeed runs the LCG twice, stores the second result back to
  prng_state::preseed, and returns the two halves recombined. The operand order
  in the final or-expression decides whether the mask or the shift is scheduled
  first; taking the shifted half first matches.

Authored by Claude (Opus 5) under human direction. All five verified at score 0.
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. None carries a
region conditional, so US alone is sufficient.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 18:09:57 -07:00