mirror of
https://github.com/pret/pmd-sky.git
synced 2026-09-29 13:47:50 -05:00
c92e8d2edb2862474dcc800d7c0db605c7f2ebfb
1587 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c92e8d2edb | Add build support with metroskrew port of compilers | ||
|
|
d333d010b6 | Fix os_ownerInfo case so that a case-sensitive linker finds the object | ||
|
|
bd75b79bc2 | Add ability to build using wibo | ||
|
|
c8073235b3 |
Merge pull request #300 from CecilArmitais/decomp-continued
Some checks failed
build / build (push) Has been cancelled
[Claude] Decompiled 538 functions; cleared 50 asm files; six shared-type corrections |
||
|
|
7487d6f73d |
Address PR #300 review: restore field comments, de-duplicate a forward
declaration, fix case indentation Six review comments from AnonymousRandomPerson on pret/pmd-sky#300. Comments restored, in include/common.h (struct ground_monster's level, level_at_first_evo, level_at_second_evo, iq and max_hp) and in include/ground_bg.h (BmaHeader's numLayers, hasDataLayer, hasCollision). These were not removed deliberately: each line was rewritten for a type correction and its trailing comment went with it. Every one of those retypes is the same character width as what it replaced, so the original column alignment is restored verbatim. struct team_member keeps u8 flags, with the labelled bitfield preserved as a comment in the form struct item already uses for the same situation. struct ground_monster; is no longer forward-declared anywhere. All three headers that carried it - main_02055410.h, main_02056914.h and main_0205A288.h - now include common.h instead. main_02056914.h previously had no includes at all, so this makes it self-contained as well. Case indentation in src/main_0203D538.c and src/overlay_29_0231CBC8.c. The defect was wider than the two labels the review pointed at: whole regions were de-indented, consistent with a splice artifact. overlay_29_0231CBC8.c's switch ran at column 8, then 4, then 0, then 4; main_0203D538.c had two contiguous blocks short by 4 and by 8. Re-indented by brace depth, so every switch in both files is now internally consistent with its own earlier cases. The comments in this commit were added under build-tools/precommit.py's --allow-comments override, which exists for exactly this case: they were requested by the upstream maintainer in review, not authored here. Authored by Claude (Opus 5) under human direction. Proved byte-neutral rather than argued, because two of these changes could in principle move codegen: the eight translation units reaching any of the three edited headers, and the two re-indented files, each compiled in the build image with the real flags (including -W all -W pedantic -W error) before and after. All 30 objects are byte-identical across NORTH_AMERICA, EUROPE and JAPAN. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
222afee8cb |
Rename three padding members to the documented field_0x<off> form
struct unk_022C593C and struct unk_023535DC in src/overlay_29_02308FBC.c were
introduced by this branch with padding members named filler, filler1 and
filler2. That spelling has no precedent in the tree: the only filler-style
names at
|
||
|
|
457a2aaf17 |
Decompile 8 more functions; clear four asm files entirely
Clears asm/main_02048B74.s, asm/overlay_29_022DC314.s, asm/overlay_29_022E9628.s and asm/overlay_29_023456BC.s, with their .inc headers and main.lsf entries. New translation units, both created with extract_function.py -nm rather than merged, to keep a small callee out of the same TU: - src/overlay_29_022E9628.c (GetRandomTile, FindNearbyUnoccupiedTile). A backward merge would have landed these beside GetLeader in src/dg_uty.c, where -O4,s can inline it; and dg_uty.c declares DUNGEON_PTR as the INCOMPLETE array form, while these two were scored against the complete [2] form. The two spellings are not interchangeable (see MATCHING_TIPS, "DUNGEON_PTR: the lever is the COMPLETENESS of the declared type"), so the file keeps [2] and src/overlay_29_023456BC.c keeps [] deliberately. - src/overlay_29_023456BC.c (RemoveGroundItem, DisplayItem). Same reason: src/overlay_29_02345698.c holds the three-instruction EntityIsValid__02345698, which both of these call. Backward merges where that was safe: - sub_02048B74 -> src/main_02048B48.c - ov29_022DC314 / ov29_022DC33C / ov29_022DC544 -> src/poly_text.c, which already owns the buffer type ov29_022DC33C takes. DECLARATION CHANGES, all measured byte-neutral rather than argued. Each file below was compiled before and after with the real build flags (-W all -W pedantic -W error) and produced a byte-identical object: - src/main_02048BB4.c: _020AFF38 scalar -> incomplete array, and its five accesses. The array form is what sub_02048B74 matches under; the two TUs that declare the symbol now agree. - src/overlay_29_022E99F0.c + include/overlay_29_022E99F0.h: the three FindNearby* wrappers retyped struct position* -> bool32, and the three DISPLACEMENTS_* externs const s32[] -> const struct position[]. The asm indexes them with lsl #2 and then reads two signed halfwords four bytes apart, which const s32* cannot produce, and the rodata decodes as {s16 x, s16 y} pairs. The return retype is safe because all four call sites already use the result as a boolean and none takes it as a pointer; FindFarthestUnoccupiedTileWithin2 has no C caller at all. bool32 rather than bool8 because the wrappers tail-return r0. - src/overlay_29_022DC61C.c: five stale externs replaced by an include of poly_text.h, and ov29_023538B4 retyped from u8[0x1963C] to the real struct. - src/dungeon_projectile_throw.c, src/main_020483B8.c, src/overlay_29_0230F810.c, src/overlay_29_02320764.c: stale externs replaced by includes. include/poly_text.h carried three defects, all fixed. This header is already landed and matching, and src/poly_text.c decompiles two sibling functions against it, so the layout is backed by matching code: - s16 unk17704[0xf92] ran 0x17704 -> 0x19628 and SWALLOWED the 350-element array at 0x18304. Split to [0x600], ending exactly at 0x18304, followed by struct unk_ov29_022DC240_18304_t unk18304[350]. The siblings corroborate independently: ov29_022DC240 sets unk8 = 0x40 and unka = 0x18, and ov29_022DC2B8 zeroes unk17704[i] for i < unk8 * unka = 0x600. - s16 unk19628 -> u16; the target loads it with ldrh. - `} unk1962a;` was a file-scope tentative definition inside a header, which MWCC emits as a DEFINED symbol, so a second includer collides. Deleting it is NOT object-neutral (1000 -> 928 bytes); it is MOVED into src/poly_text.c, which is object-neutral and was verified as such. ov29_022DC33C reads an uninitialised local, and that is a property of the ROM: the target does `ldrh r3, [sp]` before anything stores to that slot. -W error rejects the direct spelling, and neither a one-member struct nor a one-element array suppresses it. Reading and writing through a pointer local satisfies the diagnostic and emits nothing; landcheck confirms 130/130 words byte-identical. include/overlay_29_022E99F0.h gains #include "dungeon_mode.h". The bug was latent, not introduced: the header named struct position without defining it and compiled only because its struct position* RETURN type introduced the tag at file scope. Retyping the return to bool32 removed that, and every parameter list then declared its own scoped type. Authored by Claude (Opus 5) under human direction. Every function was byte-compared against the assembly it replaced with build-tools/landcheck.sh before any build, and every edit to an already-landed file was proved byte-neutral by an object diff. 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> |
||
|
|
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> |
||
|
|
c482e2dfdb |
Decompile 59 more callees; clear five asm files entirely
asm/main_020504BC.s 28 functions cleared asm/main_0200D1F0.s 11 functions cleared asm/main_02052060.s 10 functions cleared asm/overlay_29_02320788.s 8 functions cleared asm/main_020559D8.s 1 function cleared asm/overlay_29_022E34A8.s 1 of 9 remainder -> overlay_29_022E2B68.s sub_02050CF8 and sub_02050D84 are in translation units of their own, src/main_02050CF8.c and src/main_02050D84.c, and that is load-bearing rather than tidiness. Both call BitstreamDebug, which is four bytes -- an empty body -- and is one of the other 26 functions of the same asm file. Compiled beside it at -O4,s, mwcc inlines the call away and each function comes out two instructions short; the ROM then shifts and 33 of 37 sbins stop matching. Retail emits a real bl there, so retail compiled these two apart from BitstreamDebug. Separate objects reproduce that, and the pool -- five words and the predicated ldrne/ldreq pair -- was never the problem. asm/main_bss_022AB0AC.s declares a second global at 0x022AB918. Two objects of different size share that address: the record TEAM_NAME (0x14 bytes, 0x10 under JAPAN) and _022AB918, its leading name buffer (0xC, 8 under JAPAN). Four functions load both, which needs two distinct (symbol, addend) pool keys; one symbol gives one word and leaves them four bytes short. No .space is added and no later symbol moves, so the bss layout and the ROM are untouched -- confirmed by building that one-line change alone against the previous commit. ov29_022E34A8_EU exists only in the EUROPE build, so its definition and its prototype both carry #ifdef EUROPE; its single call site was already inside one. Note that extracting it left an orphan #endif in the remainder file, because it was the first function in its .s and sat inside a region conditional -- the tool takes the opening directive with the function and leaves the closing one behind. struct bag_items loses fill2/fill3/fill4 for the members behind them, so struct bulk_item moves above it and two accessors return struct bulk_item *. struct unk_020517F4 splits u8[8] into u8[4] + s32, forced by a 32-bit load at offset 4. struct bitstream::ptr becomes u8 * -- CopyBitsTo and CopyBitsFrom read it with ldrb, and char * under -char signed emits ldrsb. sub_02051FF0 and LoadFileFromRom take a const char * path, not a u32 id; src/ground_bg.c already declared the latter correctly. Seventeen call-site-derived declarations are removed in favour of an include of the owning header. Authored by Claude (Opus 5) under human direction. 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> |
||
|
|
143395893f |
Decompile 119 more callees; clear four asm files entirely
asm/main_0200F884.s 38 functions
asm/main_0202F190.s 26 functions
asm/overlay_29_022E5650.s 39 functions
asm/overlay_29_023047DC.s 16 functions
All four objects leave main.lsf and no new object is created.
Four shared types change, each forced by a load the current declaration cannot
produce, and each proven layout-preserving with the real compiler rather than
asserted.
struct monster's 0x19C..0x20F becomes `struct unk_02304D20 field_0x19c[4]` plus
two s16, replacing 112 lines: a `struct position pos`, 110 u8 placeholders and
`u16 walk_anim_frames_left`. Two functions index monster+0x19C with a stride of
0x1C (smulbb/smlabb against #0x1c) and a bound of 4, and element 0 aliases the
old pos at 0x19C and walk_anim_frames_left at 0x1B4 (= element 0 + 0x18).
Nothing in src/ reads either absorbed name through a struct monster *.
struct entity's field_0xac and field_0xad become one s16: ov29_02304830 reads
entity+0xAC with ldrsh, which no pair of u8 members can produce and no cast at
the read site can fix. Neither name is used anywhere else.
struct bag_items replaces fill2/fill3/fill4 with the members behind them --
two 1000-element arrays, four scalars and two 2-D struct bulk_item arrays -- so
struct bulk_item moves above it as a member type. Offsets are read off the asm:
the 0x300+0x8a and 0xb00+0x5a splits are forced by ARM addressing mode 3's
8-bit immediate, ldrsh vs ldrh fixes the signedness, cmp #0x3e8 fixes 1000, and
lsl #5 / lsl #4 fix the two strides. sizeof stays 0x13B4 and every following
member keeps its offset. GetCurrentKecleonShop1ItemByIndex and
GetCurrentKecleonShop2ItemByIndex return struct bulk_item * as a consequence.
window.h's portrait_params gains a `Point offset` in place of two u32 members,
and Point moves above it. UpdatePortraitBox loads the pair with
`add r1, r4, #0xc; ldm r1, {r1,r2}`, and mwcc emits ldm only when the base
points exactly at the object; two separate member reads scored 860. Every
object in the 25 translation units that reach window.h is byte-identical
before and after.
PlayEffectAnimationPixelPos was declared taking a struct entity * and returning
void; it takes a struct pixel_position * and returns s32, so ov29_022E563C's own
signature changes with it. Two declarations packed onto one physical line in
src/overlay_11_02307334.c are removed, and two in src/overlay_29_0230558C.c are
replaced by an include -- those four would have been hard errors the moment the
new headers landed.
SetAndPlayAnimationForAnimationControl's prototype here was derived from the
call site and had three parameters wrong. Its prologue reads the first three
stacked arguments as ldrb [sp,#0x18], ldr [sp,#0x1c], ldrb [sp,#0x20] and
ldrb [sp,#0x24], so parameters 5, 7 and 8 are u8, not u32.
That is what entity::field_0xaa turned on. Upstream made the member s8 in
|
||
|
|
637d196646 |
Decompile 86 more callees; clear three asm files, split a fourth
asm/overlay_29_022E4BB4.s 26 functions cleared asm/overlay_29_0230D088.s 25 functions cleared asm/overlay_29_022EA008.s 13 functions cleared asm/main_02055894.s 22 of 23 split sub_020559D8 is at score 75 (0 structural rows, 11 register-colouring rows) and is NOT landed, so main_02055894.s splits: asm/main_020559D8.o holds that one function between src/main_02055770.o and src/main_02056294.o. Five struct ground_monster members are retyped, on load-width evidence from sub_02055E14: level, level_at_first_evo and level_at_second_evo are read ldrb though declared s8, and iq and max_hp are read ldrsh though declared u16. The reading validates itself -- id at 0x4 is read ldrsh and is already declared s16, and every member whose declaration is already correct reads exactly as declared. A cast at the read site cannot fix this: MWCC takes the load's width AND signedness from the declared member type alone. This deviates from pmdsky-debug's s8/u16, and it narrows ApplyGummiBoostsGroundMode's second parameter from u16 * to s16 * -- that function is still asm, so its prototype is now pinned by this reading rather than by its own body. struct dungeon's `u8 field_0x1c; u8 field_0x1d;` become one s16, forced by ldrsh/strlth at 0x1c. 0x1C is 4-aligned and 0x1E is already s16, so no padding appears and no offset moves. No other translation unit names either field. sub_0205B008's second parameter becomes struct ground_monster * instead of u32: it forwards the argument straight to sub_02055894, and both asm call sites load r1 with `ldr r1, [r0, #0x3c]`, a word out of a struct field. src/overlay_29_022E9FC0.c declares DUNGEON_PTR with a COMPLETE type, [2] rather than []. ov29_022EA008 scores 1025 under the incomplete form: it lets mwcc keep DUNGEON_PTR[0] live across a store the target reloads after. [] and [2] are compatible types, so no use site changes. struct unk_02353560 in that file grows from 5 to 0x10 bytes and struct unk_0237C850 is new; neither is named outside it. Twelve message ids in src/overlay_29_0230BBAC.c get an #ifdef JAPAN block. Every other region delta across the four files is a header-driven field displacement and needs nothing. Thirty-five pre-existing declarations across nineteen files are removed in favour of an include of the owning header, or corrected in place. Eleven of them disagreed with the definition: UnkMapRelatedFunc declared with an unsigned first parameter in four files where the switch dispatch is a signed range test, six declared with no prototype at all and the wrong return type, and one (sub_02055894) declared as taking a u32 where it takes a pointer. Authored by Claude (Opus 5) under human direction. 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> |
||
|
|
6f3ad6941c |
Decompile 48 more callees; clear four asm files entirely
Every function of four whole asm files now matches, so all four objects leave main.lsf and the .s/.inc files go: asm/overlay_29_023055B0.s 4 functions asm/overlay_29_02314810.s 9 functions asm/overlay_29_022E7EC4.s 25 functions asm/main_0202AB94.s 10 functions struct unk_0202AAA8 gains four members carved out of existing byte padding: a u32 at 0x0, the third menu kind's flag word plus its initial selected index at 0xFC/0x100, a u8 * at 0x160, and a signed s32 at 0x1A8. Offsets and sizeof are unchanged (0x1C8), proven by compiling one offsetof assertion per member with mwccarm and reading the folded constant back; the check carries a negative control that correctly fails, so "all as expected" is an outcome it could have missed. Nothing in the tree read any of the four offsets. struct struct_2 moves from include/overlay_31_02382820.h to include/window.h so a src/main_* file can reach it. CreateSimpleMenuInternal copies it whole (0x98 bytes), so its size is load-bearing. It is a pure move; the name is pre-existing and unchanged. window.h rather than main_0202AAA8.h because the latter drags main_0202AB40.h's prototypes into overlay_31_02382820.c, where they collide with that file's own declarations. Four data symbols declared `extern s32` from a call site whose parameter was void * are given their real types: _0209C85C and ov11_02322CC8 are WindowTemplate (each measures exactly 0x10 to the next symbol, and WindowTemplate is 16 bytes), _0209C86C and ov11_02322CF0 are struct unk_0202A5CC[] (8-byte records, matching the element counts the call sites pass). Each had exactly one user. The (s32) cast at overlay_11_02307334.c's call site goes with them -- field_0x1c is already a struct struct_2. Region arms, all message ids: overlay_29_0230558C.c gains a JPN_MSG_OFFSET block for five ids; move_orb_effects.c reuses its existing one and adds MESSAGE_ED0 / MESSAGE_ED1 for the two that shift by -0x2BE rather than the file's flat -0x2C0; overlay_29_02315118.c gains five named defines because it has no offset constant of its own. Every other region delta in these four files is a header-driven field displacement and needs nothing. Nine call-site-derived declarations across six files are replaced by an include of the owning header. Four declared void where the function returns bool8; two declared an s8 return where it is s32; three took an s8 parameter where it is s32. One was the fifth extern on a single physical line, which a line-oriented grep does not see. Authored by Claude (Opus 5) under human direction. 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> |
||
|
|
0f3cbcbcd2 |
Decompile 26 more callees; clear three asm files entirely
Closes the three near-match groups left from the previous batch. All of asm/overlay_29_02337EC0.s 6 functions asm/overlay_29_022E335C.s 10 functions asm/overlay_29_0230F02C.s 10 functions now match, so the three objects leave main.lsf and the .s/.inc files go. struct dungeon gains struct unk_02337EE8, grouping the ten members from 0x286B0 through spawn_table_entries_chosen into one sub-object at unchanged offsets. ov29_02337EE8 and GetRandomSpawnMonsterID reach spawn_entries_master through a local pointer to that member, which is what makes mwcc form the member base and the inner offset as two additions the way the target does; the sub-object alone, or the local alone, still scores 225. The spelling is already in the tree at src/overlay_29_022FBBEC.c:72 for the other grouped member. Eighteen expressions in seven files gain field_0x286b0; four of them are in upstream's src/overlay_30_init.c, which reaches highest_enemy_level and spawn_table_entries_chosen directly. Two width corrections, each replacing adjacent u8 members with one wider member at the same offset, so no following offset or alignment moves: dungeon::number_completed_floors u8 -> s16, absorbing speed_boost_counter at 0x1F (read ldrsh in three places, written strh in a fourth); and monster::field_0x188, four u8 -> one s32 (read ldr twice here, written str in overlay_29_022E0378). src/dg_camera.c declares DUNGEON_PTR as struct dungeon *[2] rather than the incomplete *[]. A complete type is what makes mwcc reload the pointer across an intervening store, which ov29_022E34C8 needs; [] and [2] are compatible types, so no use site changes. src/dungeon_map_access_1.c takes the scalar form for the same reason. Sixteen call-site-derived declarations in twelve files are replaced by an include of the owning header. Eight of them declared PlayEffectAnimationEntity with the wrong tail types -- s32, s32, s32 where its prologue reads u8, s16 and a pointer. Every affected call site passes literals, so the correction is byte-neutral, which the build confirms. Authored by Claude (Opus 5) under human direction. 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> |
||
|
|
967fe53b74 |
Decompile 17 more callees; clear two asm files; enum item_id gains ITEM_INVALID
Two .s files cleared entirely, so main.lsf loses both objects:
asm/overlay_29_022FB678.s AreEntitiesAdjacent, IsHero, ov29_022FB718,
ov29_022FB83C, ov29_022FB920, ov29_022FB984,
ov29_022FB98C, ov29_022FB9BC
asm/main_02003328.s TaskProcBoot, EnableAllInterrupts, sub_02003620,
sub_02003704, sub_02003754, sub_02003780,
sub_020037A4, GetTime, DisableAllInterrupts
main_02003328 lands as TWO objects, not one. GetTime calls EnableAllInterrupts,
which precedes it in address order, and at -O4,s MWCC folds a callee whose body
it has already seen: in one translation unit GetTime's two bl EnableAllInterrupts
become the inlined body. So GetTime and DisableAllInterrupts go to a new
src/main_020037B4.c; the other seven merge into src/main_0200330C.c.
DisableAllInterrupts is not inlined in the same run because it is defined after
GetTime, which is the same rule seen from the other side.
enum item_id gains ITEM_INVALID = -1, placed as MONSTER_INVALID is in
enum monster_id. Under -enum min an enum with no negative enumerator is
unsigned, so a field of that type compiles to ldrh where AuraBowIsActive's
target has ldrsh; a cast at the call site cannot fix it, which was measured.
Range becomes -1..1399, still two bytes. VERIFIED IN ISOLATION -- added alone,
nothing else changed, all three ROMs still matching -- so it is byte-neutral for
existing code, the same standard ENTITY_NONE and MONSTER_INVALID were held to.
Five call-site declarations are replaced by an include of the owning header.
Two were wrong, not merely redundant: ov29_022FB984 was declared void where it
returns bool8, and ov29_022FB98C was an unprototyped extern int for a function
that returns nothing and takes two struct entity *.
Authored by Claude (Opus 5) under human direction. Each function was measured at
decomp.me score 0 in every region it exists in and re-measured by an independent
verifier. Confirmed by matching builds of 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>
|
||
|
|
92774e8a2b |
Decompile the head of overlay_11_023090DC; type the parent-menu tables
Five functions, the head of asm/overlay_11_023090DC.s, all merging into src/overlay_11_02307334.c beside their only caller ov11_02307334: ov11_023090DC 809 insn (NA/EU), 807 (JAPAN) ov11_02309DAC 18 ov11_02309DF8 10 ov11_02309E24 8 ov11_02309E48 39 ov11_023090DC is the largest function landed on this branch. It reached STRUCT 0 -- every instruction, immediate and branch target correct -- while a single register permutation over 35 rows held it at score 230. The rule that closed it: MWCC colours the locals living across a call in case-scope declaration order, lowest free register first, and a local assigned only inside a loop body does not join that group from case scope. Four qualifying locals therefore reach only r4-r7; the target needs one on r8, so a fifth member has to exist. Hoisting e, move_id, k and q into the case's declaration list supplies it. No statement moved and no type changed. struct unk_02324D90 gains 22 offsets, replacing padding. Size and every pre-existing offset are unchanged in all three regions, checked by compiling sizeof/offsetof comparisons against the previous layout with the real compiler and reading the folded constant back out. The parent-menu tables are typed from their data rather than from the weakest prototype that accepted them. asm/overlay_11_022ECD24_data.s shows each as a run of 8-byte entries -- u16 string id, 2 bytes padding, s32 value -- i.e. struct unk_0202A5CC, which include/main_0202A66C.h already declares and which CreateParentMenuFromStringIds already takes. Four were declared extern s32 as scalars (hence the & at every call site), one duplicated the struct under a second name, and this file carried its own void*-taking prototype that let all of it compile. Seven globals are now struct unk_0202A5CC[], the duplicate struct unk_02322D38 is gone, the local prototype yields to the header, and five redundant & are dropped. Byte-neutral: &scalar and array yield the same address. Authored by Claude (Opus 5) under human direction. All five measured at decomp.me score 0 in all three regions and re-measured independently. Confirmed by matching builds of 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> |
||
|
|
964beafb7d |
Decompile 38 more callees; clear five more asm files entirely
Thirty-eight functions in nine groups, each group clearing a .s file's head or
the whole file so nothing splits:
asm/overlay_29_0231AFB4.s ov29_0231AFB4, ov29_0231B008, ActivateMotorDrive,
TryActivateFrisk (whole file)
asm/overlay_29_022FBC4C.s CountActiveMonsters, ov29_022FBC94,
ov29_022FBD08, ov29_022FBD24, ov29_022FBD80
(whole file)
asm/overlay_29_02302388.s ov29_02302388, UpdateStateFlags,
IsProtectedFromNegativeStatus, ov29_023024E0,
AddExpSpecial (whole file)
asm/main_02051098.s sub_02051098, sub_020510C0, MtInit, MtNext
(whole file)
asm/main_02055528.s IsMainCharacter, GetTeamMember,
GetRecruitMentryIdBySpecies (whole file)
asm/overlay_29_023350FC.s ov29_023350FC, TryWeatherFormChange
asm/main_020562B8.s sub_020562B8, SetActiveTeam, sub_02056318,
sub_0205633C, sub_02056360, GetActiveTeamMember
asm/overlay_29_022F0654.s MakeTargetFaceUserAndIdle, ov29_022F067C,
ov29_022F0780
asm/main_02013C30.s GetMovesetIdx__02013CAC, IsReflectedByMagicCoat,
CanBeSnatched, FailsWhileMuzzled, IsSoundMove,
IsRecoilMove
Five files are consumed entirely, so main.lsf loses five asm objects.
ov29_022FBD08, ov29_022FBD24 and ov29_022FBD80 do not exist in the JAPAN build:
they sit inside one #ifndef JAPAN in the .s, so their definitions and their
prototypes carry the same guard.
include/dungeon.h gains struct unk_022FBD24, grouping the two members at 0x3DCC
and 0x3E1C into one sub-object. Layout is byte-identical -- u32[20] then u32, same
order, same offsets -- but the grouping is what makes MWCC materialise the single
base register the target uses; without the type src/overlay_29_022FBBEC.c does not
compile. The four comment lines move verbatim with the members.
struct unk_022C4C6C::field_0x0 is enum type_id, not u8: it feeds
monster->types[0]. enum type_id maxes at 18, so -enum min keeps it one byte and
the layout is unchanged.
src/special_move_types.c declares DUNGEON_PTR as [2], not the [] the tree usually
writes. With the incomplete array type MWCC hoists the ldr out of the outer loop
of ov29_0231AFB4 and ov29_0231B008 (scores 460 and 515); 8 bytes is the symbol's
measured extent and [] and [2] are compatible types, so nothing else changes.
Eighteen call-site declarations are replaced by an include of the owning header.
Three were required rather than cosmetic: two K&R `extern int ov29_022FBD24();`
and `extern int ov29_022F0780();` with the wrong return type, and a
GetActiveTeamMember declared (int) against the definition's s32.
Authored by Claude (Opus 5) under human direction. Each function was measured at
decomp.me score 0 in every region it exists in, and re-measured by an independent
verifier. Confirmed by matching builds of 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>
|
||
|
|
9b3650fe33 |
Decompile 26 more callees; clear six asm files entirely
Twenty-six functions across twelve groups, each group chosen so it clears a
.s file's head or the whole file, never splitting one:
asm/overlay_29_0231EDFC.s TryHurl
asm/overlay_29_0230E064.s TryRecruit
asm/overlay_29_0234B130.s ov29_0234B130, ov29_0234B1A4,
LogMessageByIdWithPopupCheckParticipants,
WaitUntilAlertBoxTextIsLoadedWrapper,
LogMessageByIdWithPopupCheckUser,
LogMessageWithPopupCheckUser, LogMessageByIdQuiet
asm/overlay_29_0231B1B8.s TryActivateBadDreams
asm/overlay_29_02301D84.s OtherMonsterAbilityIsActive
asm/main_02050300.s SetItemAcquired
asm/overlay_29_0230F9A4.s ov29_0230F9A4, TrySpawnEnemyItemDrop
asm/main_02051504.s RetrieveFromItemList1, IsForbiddenFloor
asm/main_020251F0.s sub_020251F0, StrncpySimpleNoPadSafe
asm/main_020261F4.s sub_020261F4, sub_02026204, DrawTextInWindow
asm/main_0202B568.s sub_0202B568, GetSimpleMenuResult__0202B870
asm/main_020022C4.s sub_020022C4, sub_020022D0, RandIntSafe
Fourteen are callees of the ten previously landed functions; the rest are the
neighbours that had to clear first to reach a file boundary. Six .s files are
consumed entirely, so main.lsf loses six asm objects and gains six tails.
Thirty-five call-site declarations are replaced by an include of the owning
header, across twenty-one files. Several were not duplicates but genuine
disagreements: GetSimpleMenuResult__0202B870 had five declarations, all giving
the window id as s8 against the definition's s32; two were K&R
`extern int ov29_0234B1A4();`. None of these can surface in a build, since two
declarations in two translation units never meet.
A declaration that disagrees is NOT automatically stale. src/overlay_13_0238BDA8.c
keeps its own `extern void DrawTextInWindow(s8 window_id, ...)`: that file's
DrawPersonalityTestDebug carries the window id in an s8 local, and against the
header's s32 the call needs a sign extension retail does not emit. Replacing it
broke OVY_13.sbin. Retail's translation units genuinely disagreed about this
prototype, so the per-TU declaration is evidence, not a defect to tidy away.
Three shared types change, all layout-preserving:
* struct team_member's first byte, a 1+7 bitfield pair, becomes u8 flags.
TryRecruit writes the whole byte in one strb and reads bit 0 through
GetFlag(u8, u8), which takes a value a bitfield member cannot supply.
* struct unk_02026130's field_0x4 grows from [4] to [0x118] (total 0x11C).
DrawTextInWindow declares one as a local, so its size sets the frame.
* alert_box_info::alert_box_window_id becomes s8; it holds -2, and seven
ldrsb reads of offset 0xCEC corroborate the signedness.
sub_02026194 is corrected from one argument to three: sub_02020BC4 reads r1
and r2 (tst r1, #0x400; strh r1, [r4, #0x60]; str r2, [r4, #0x88]) and every
asm caller passes all three, so the wrapper was forwarding registers it never
named. Its pre-landing asm was recovered from git and both forms measured.
Authored by Claude (Opus 5) under human direction. Each function was measured
at decomp.me score 0 in all three regions and re-measured by an independent
verifier. Confirmed by matching builds of 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>
|
||
|
|
49da4ee98e |
Decompile 12 more callees; clear the head of overlay_11_02308D1C
Twelve contiguous functions from the head of asm/overlay_11_02308D1C.s,
merged into src/overlay_11_02307334.c so the .s splits rather than the
source file:
ov11_02308D1C ov11_02308D48 ov11_02308DD8 ov11_02308EB4
ov11_02308EDC ov11_02308F14 ov11_02308F4C ov11_02308FD0
ov11_02308FEC ov11_0230901C ov11_02309040 ov11_02309084
Ten are callees of ov11_02307334; ov11_02308D1C and ov11_02308D48 are the
head neighbours that had to clear first for the run to reach a file
boundary. The remainder of the file becomes asm/overlay_11_023090DC.s,
which keeps the OV11_02309084_OFFSET definition its 24 users need.
include/overlay_11_02307334.h gains struct unk_02309DAC, struct
unk_02308F4C and the twelve prototypes; nine superseded void*-typed
forward declarations in src/overlay_11_02307334.c are removed.
Two file-local types in src/overlay_11_02307334.c change. struct
unk_02324D90 is added, its second member region-split (JP 0xF0 against
0x110 elsewhere). struct unk_02324D8C's u8 field_0x104[0x134] splits into
u8 field_0x104[0x32] plus char field_0x136[0x102] -- same size, same
layout, naming the offset ov11_02308DD8 writes through. Neither type
appears outside this file.
Authored by Claude (Opus 5) under human direction. Confirmed by matching
builds of 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>
|
||
|
|
7f1656cfc9 |
Decompile 11 more callees; two cheap neighbour clusters
Each was verified at score 0 against its NORTH_AMERICA, EUROPE and JAPAN targets before landing, with the address walk closing exactly in each region, and by a matching US build after. overlay_29_0231E9F0.c InitMoveWrapper, MoveIsNotPhysical, CategoryIsNotPhysical overlay_29_022E45B8.c ov29_022E45CC, ov29_022E45D0 overlay_29_022F0590.c UnfreezeAnim overlay_29_02311010.c TickNoSlipCap dungeon_logic_6.c ov29_022EFB84 main_02062A58.c sub_02062AD0 main_0200224C.c AddFixedPoint64 main_0202A66C.c CreateParentMenuFromStringIds All eleven merge into an adjacent source file; no assembly file is split. Two of them were bought cheaply: InitMoveWrapper is four instructions and clearing it puts MoveIsNotPhysical and CategoryIsNotPhysical at the file head, and ov29_022E45CC is a single instruction standing in front of ov29_022E45D0. TickNoSlipCap needed a repair the compiler could not report. extract_function.py placed its generated placeholder immediately after a pre-existing `#ifdef EUROPE` in overlay_29_02311010.c, so the definition existed only in EU builds: every object compiled and the failure appeared at the link step as `Undefined : "TickNoSlipCap"`, referenced from ActivateEndOfTurnEffects in the same object. Moving it out of the block then exposed two of its own declarations that had been invisible while the region never compiled it. main.lsf confirms the merge target itself was right -- asm/overlay_29_0230F9A4.o is immediately followed by src/overlay_29_02311010.o, and the function sat at the tail of the former. build-tools/check_landed_guards.py now reports any definition at conditional depth > 0; it is clean across every function landed so far. Twelve call-site declarations are replaced by an include of the owning header. CreateParentMenuFromStringIds had THREE mutually contradictory ones -- (void*, u32, void*, void*), (u32*, u32, struct struct_2*, u32*), and the matching signature -- which could coexist only while the function had no header. Its body indexes the fourth argument as struct unk_0202A5CC throughout, so the two call sites are cast rather than the parameter weakened to void*, which would only move the casts inside. 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> |
||
|
|
2cfa18739d |
Decompile 13 more callees; all merge at a file boundary
Each was verified at score 0 against its NORTH_AMERICA, EUROPE and JAPAN targets before landing, with the address walk closing exactly in each region, and by a matching US build after. main_0200224C.c sub_02002228, ClampedLn main_020114F8.c ApplyGummiBoostsToTeamMember main_0200F798.c RemoveItemNoHoleCheck main_02062A58.c CanMonsterBeUsedForMission main_0205D11C.c CountAndPopulateValidMissionTableMonsters overlay_10_022BCC60.c ov10_022BCDF4 overlay_29_022E4338.c PlayEffectAnimationEntityStandard overlay_29_022EAC7C.c MusicTableIdxToMusicId overlay_29_022ECDC0.c ov29_022ECD84 overlay_29_022F0590.c ov29_022F0534 overlay_29_0230A9DC.c AftermathCheck dungeon_logic_6.c ov29_022EFB20 Every one sat at the head or tail of its .s, so all thirteen merge into an adjacent source file and no assembly file is split. sub_02002228 is one instruction and was taken only because it is the single function standing between ClampedLn and the end of its file. Ten call-site declarations are replaced by an include of the owning header, including three unprototyped `extern int ov29_...();` forms in src/overlay_29_02308FBC.c that became hard conflicts the moment these functions had real headers to contradict. Three implicit-conversion errors were fixed by correcting a declaration rather than by adding a cast, which is the better repair when the declaration is ours: RANDOM_MUSIC_ID_TABLE had no C declaration anywhere, so the u16 in the first draft was a guess. It is declared `enum music_id[30][4]` here; -enum min sizes that enum (max 999) to two bytes, so the layout is unchanged and the cast is unnecessary. GetBaseForm and IsMonsterMissionAllowed had no declaration either, and the invented `enum monster_id` parameters created the conversions. They take s16 here, matching the tree's own FemaleToMaleForm(s16) and HasMonsterBeenAttackedInDungeons(s16) for the same ids. One cast is kept deliberately: MUSIC_ID_TABLE entries carry a 0x8000 flag bit that the source tests and masks off, so an entry is not a valid music_id enumerator and typing that table as the enum would be false. Two generated headers are made self-contained -- overlay_29_022EAC7C.h named enum music_id and main_0200224C.h named struct fixed_point_64 without including anything, so each prototype built its own scoped tag and the definition read as a redeclaration with a different type. 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> |
||
|
|
7e1755ddf8 |
Decompile 11 more callees; give them headers and drop 40 call-site declarations
Each function was verified at score 0 against its NORTH_AMERICA, EUROPE and
JAPAN targets before landing, with the address walk closing exactly in each
region, and by a matching US build after.
main_020517D4.c GetRankUpEntry
main_02001188.c MemAlloc
main_0203088C.c CloseAdvancedTextBox
main_020114F8.c ApplyGummiBoostsToGroundMonster
main_0205283C.c GetExp
overlay_29_02305C04.c EndNegativeStatusConditionWrapper
overlay_29_02338350.c NearbyAllyIqSkillIsEnabled
overlay_29_022E9FC0.c AdvanceFrame
overlay_29_022E99F0.c TickStatusTurnCounter
overlay_29_0234B4BC.c LogMessageByIdWithPopup
overlay_29_0234B340.c LogMessageByIdWithPopupCheckUserTarget
All eleven sat at the head or tail of their .s, so every one merges into the
adjacent source file and no assembly file is split.
Forty call-site declarations of these functions are replaced by an include of
the owning header. Two of them disagreed with the real signature, and one had to
be fixed for the tree to compile at all:
MemAlloc was declared six different ways. src/overlay_24_end.c spelled it
`void* MemAlloc(s32, s32);` -- signed -- and that file already
includes main_02001188.h, so the contradiction became a hard
compile error the moment MemAlloc had a header to contradict.
It had been harmless only because the function had none.
AdvanceFrame was declared `void AdvanceFrame(u8);` in two overlay_31 files
against the real u32. Byte-neutral in practice, since every call
site passes the literal 0x62, but wrong.
struct unk_020517F4 was defined file-locally in src/main_0203D538.c. It now has
one definition, in include/main_020517D4.h, and both local copies are gone --
otherwise including that header where GetRankUpEntry is called would collide.
Two generated headers are made self-contained. extract_function.py emits a
header that names types it does not include, and since the .c includes it first,
the prototype builds its own scoped tag: include/main_020114F8.h declaring
`struct ground_monster *` before common.h defines it made the definition read as
a redeclaration with a different type.
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>
|
||
|
|
3fd44e5988 |
Decompile 16 callees of the combat and dungeon-generation functions
Every function was verified at score 0 against its NORTH_AMERICA, EUROPE and
JAPAN targets before landing, with the target's address walk closing exactly in
each region, and by a matching US build after landing.
overlay_29_0233E43C.c GenerateRoomImperfections, CreateHallway
overlay_29_022E3F20.c UpdateStatusIconFlags, PlayQuestionMarkEffect,
PlayExclamationPointEffect__022E47D4,
PlayExclamationPointEffect__022E4880, ov29_022E3E74
dungeon_util_2.c PopulateActiveMonsterPtrs, GetTeamMemberIndex,
GetMonsterOrTrapName, SubstitutePlaceholderStringTags
overlay_29_022EC7E8.c IsFloorOver (new file)
overlay_29_02345A3C.c SpawnDroppedItemWrapper (new file)
overlay_29_023061A8.c EndBurnClassStatus (new file)
overlay_29_02306728.c EndCurseClassStatus (new file)
overlay_29_02336F4C.c UpdateTrapsVisibility (new file)
Eleven were landed at a file boundary by first decompiling the functions between
them and the nearest end of their .s, so they merge into the adjacent source file
instead of splitting it. The other five sit too far from either end to make that
worthwhile and split their .s as usual.
CreateHallway closes a provisional declaration: CreateGridCellConnections had
declared it from the call site as (s32 arg1 .. s32 arg7), and that guessed
prototype is now replaced by the real one in the same header.
Eighteen pre-existing declarations of these functions, written from call sites in
other translation units, are replaced by an include of the owning header. Three
of them disagreed with the real signature, and no build could have caught any of
them because two declarations of one function never meet in a single translation
unit:
IsFloorOver declared `extern s32` in two files; it returns bool8.
SpawnDroppedItem declared `void`; SpawnDroppedItemWrapper returns its
value. Corrected in src/dungeon_projectile_throw.c.
SetPreprocessorArgsStringToName
declared with `u8 pos` / `u8 param_4`. Every existing
call site passes literal constants, where the narrowing
is invisible; SubstitutePlaceholderStringTags passes
variables, and the narrow form emits two `and rX,#0xff`
rows the target does not have. Widened to s32/u32.
GetMonsterOrTrapName is landed with three parameters rather than two. Both score
0 -- an ignored third argument costs the callee nothing, so the callee's bytes
cannot distinguish them -- but src/overlay_31_02382820.c has always called it
with three, which is evidence about the caller that the callee cannot supply.
pret/pmd-red was used as a structural reference where it has an equivalent
function. It supplied the shape and never the spelling: it is a different game
built by a different compiler. IsFloorOver is the clearest case -- translating
its nested form literally scored 1525, and flattening to four independent early
returns scored 0.
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>
|
||
|
|
dae72255ff |
Rephrase eight matched functions; drop index casts and magic numbers
Re-land eight already-matching functions in more idiomatic C. Every one was verified at score 0 in each region it has a target for BEFORE landing, and by a matching US build AFTER landing, one function at a time. CreateGridCellConnections 320 -> 278 eight (u32) index casts removed GenerateExtraHallways 170 -> 161 terrain_flags & 3 -> GetTerrainType ActivateEndOfTurnEffects 538 -> 533 MAX_HP_LIMIT for the 999 literals ApplyDamageAndEffects 316 -> 314 CalcDamage 635 -> 631 one volatile local dropped ApplyDamage 807 -> 818 ov11_022ED69C 242 -> 240 const void * -> typed pointers ov11_02307334 733 -> 735 three redundant (u8 *) casts dropped The CreateGridCellConnections index casts had been recorded as load-bearing. They are not. MWCC keys common-subexpression elimination on the address expression INCLUDING integer conversion nodes, so an `int` alias of an `s32` index splits the use-set exactly as a cast does, while a same-type copy is erased by copy propagation. An identity (s32) cast is byte-identical to the (u32) one, and casting every site is byte-identical to casting none, which is what shows the lever is the split rather than the cast. overlay_29_0233C9E8.c gains #include "dungeon.h" and "dungeon_util_static.h" for TERRAIN_TYPE_*, DUNGEON_MAX_SIZE_* and GetTerrainType. All three were already in the tree; no name is introduced here. Three candidate rephrasings were rejected on measurement and are not included: one scored 1195 in EUROPE against a landed baseline of 10, one carried an artificial `damage_data++; damage_data--;` pair, and one did not match at all. Authored by Claude (Opus 5) under human direction. Confirmed by a matching build after each individual change: build/pmdsky.us/pmdsky.us.nds: OK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
4c7fe63636 |
Decompile CreateGridCellConnections (0x0233E43C)
573 instructions in overlay_29, the immediate neighbour of GenerateExtraHallways. No region preprocessor directives -- all three regions assemble identical text, so one source serves US/EU/JP. asm/overlay_29_0233CF84.s is split: the function becomes the new pair src/overlay_29_0233E43C.c + include/overlay_29_0233E43C.h, and the remainder becomes asm/overlay_29_0233ED34.s. main.lsf gains two objects. The header adds a provisional prototype for CreateHallway, which had no C declaration anywhere in the tree. Its arity of 7 is read off its own prologue (ten pushed registers, no sub sp, and reads at [sp,#0x28]/[sp,#0x2c]/[sp,#0x30]); the parameter types are the loosest that fit and the names are positional placeholders. struct unk_0233C9E8 and FLOOR_GENERATION_STATUS come from include/overlay_29_0233C9E8.h, landed by the previous function; the grid's 450/30 strides and 450/30 = 15 confirm the (*)[15] shape independently here. 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> |
||
|
|
fd3564d312 |
Decompile GenerateExtraHallways (0x0233C9E8)
356 instructions in overlay_29. No region preprocessor directives -- all three regions assemble identical text, so one source serves US/EU/JP. asm/overlay_29_0233AE84.s is split: the function becomes the new pair src/overlay_29_0233C9E8.c + include/overlay_29_0233C9E8.h, and the remainder becomes asm/overlay_29_0233CF84.s. main.lsf gains two objects. The header carries two placeholder types the function needs and the tree did not have: struct unk_0233C9E8, the 30-byte dungeon grid cell (no such struct existed, and the grid is a stack local in every caller, so it has no global to key a name on), and struct unk_0237CFBC for FLOOR_GENERATION_STATUS, which had no C declaration anywhere. That symbol's asm reserves .space 0x4 but this function reads byte +6, so the declaration is sized to what is used. Authored by Claude (Opus 4.8) under human direction. Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
2447a0200d |
Decompile GenerateMission (0x0205D224)
864 instructions, a 19-step pipeline with five jump tables. No region preprocessor directives -- all three regions assemble identical text, so one source serves US/EU/JP. asm/main_0205D1F4.s is split: GenerateMission merges into src/main_0205D11C.c and the remainder becomes asm/main_0205DFAC.s. main.lsf swaps the object in place. include/main_0205D11C.h gains struct unk_0205DFAC (the 6-byte record), struct unk_0205D224 (the 0x22-byte template) and the prototype; CheckItemForMissionType's second parameter is corrected to union mission_subtype *. Authored by Claude (Opus 4.8) under human direction. Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
240bea143d |
Decomp ov11_02307334; correct three callee declarations it exposes
ov11_02307334 (0x02307334, 1624 instructions in all three regions) is the TM/HM use flow: a 42-case dense switch over *ov11_02324D8C, driving the bag inventory menu, the TM info and confirmation dialogues, the gummi/IQ path and the move-forget flow through menus, text boxes and scroll boxes. It is function 145 of 215 in asm/overlay_11_022FE5F8.s, so extract_function.py splits rather than merges: the 70 functions after it move to asm/overlay_11_02308D1C.s, the function lands in src/overlay_11_02307334.c with include/overlay_11_02307334.h, and main.lsf lists both new objects where it listed one. Unlike the last three functions on this branch there is no stale extern to reconcile. The symbol has exactly one caller, ov11_02304B4C, in the same object and still in asm; it has no external linkage today, appears in no function-pointer table, and a scan of all 512 .s files for the little-endian encoding of its address finds nothing. Three declarations elsewhere in the tree are wrong and this function is the first caller that makes them matter. RemoveItemNoHoleCheck takes an item index, not a struct item *: asm/main_0200F390.s does mov r1,#6 / smulbb r1, r0, r1, and SMULBB multiplies the low halfwords, so the argument is a signed 16-bit value scaled by sizeof(struct item). Its only other caller passes GetFirstUnequippedItemOfType, which likewise returns an index rather than a pointer, so the two errors cancelled and the pair matched by accident. ov10_022BCDA8 is declared void but its body ends in sub_02033064, which returns s32, and both of this function's call sites consume the result. All three are -W error blockers here, and the matching build confirms the fixes are byte-neutral. Case emission order is source order and is not ascending: 0, 2, 1, 3, 17..25, 33, 34, 31, 32, 35..40, 26..30, 41, then 4..16 last. Every case breaks to a single trailing return 0; case 16 returns 1, and case 15 falls through into it. The eight function-scope locals are declared in descending stack-address order because MWCC gives the first-declared local the highest address, which tiles the frame exactly to 0x5A0. The 43-instruction block shared by cases 32 and 34 is written out twice rather than factored into a helper - MWCC 2.0 does not tail-merge blocks of that size, and the target has both copies. Several shapes that read as redundant are load-bearing and reproduce the target: case 4's v1 != 8 && v1 == 4, the dead field_0x0 = 0x1a in case 38 and field_0x24e = v6->id in case 1 that the following if/else overwrites in both arms, the guard if (field_0x8 == -2) ov11_02308EDC() in case 12 that the callee performs again itself, and case 21's two search loops being written differently. struct unk_02324D8C is a placeholder for the 0x330-byte state struct MemAlloc'd by ov11_02307244, with field_0x<off> members, three identified sub-object types where the arithmetic closes, and u8 filler elsewhere. The 0x14-byte object at 0x238 has to be a real nested struct: the target holds base + 0x238 in a callee-saved register across two calls, while flat fields make MWCC round the base to #0x200 and re-offset per use. The 49 callees with no declaration anywhere are declared extern in the .c with prototypes read off their own asm; every name is established by a literal bl in the target, but the argument types are inference. Region handling: three file-scope offset macros under JAPAN cover the id families at +0x2D20 (16 sites), +0x1458 and +0x1567, and the two genuine three-way forks - the StringFromId base in case 1 and the CreateScrollBoxSingle base in case 10 - are written out per region as src/get_category_string.c and src/overlay_25_init.c already do. The asm's four #ifdef JAPAN code forks need no #if here: each exists only because exactly one of the two constants is an ARM rotated-8-bit immediate, so writing id + OFFSET and letting MWCC choose mov versus a pool word reproduces all four. EUROPE differs from NORTH_AMERICA in two constants and nothing else. Authored by Claude (Opus 5) under human direction. Confirmed by matching builds of 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> |
||
|
|
f47593d94e |
Decomp sub_0203D538; replace its stale extern with the new header
sub_0203D538 (0x0203D538, 1666 instructions in US and EU, 1640 in JP) is the mission-reward state machine: a 77-case dense switch over MISSION_REWARD_STRUCT_MAIN_PTR->field_0x0 driving money, egg, item, rank-up and recruit rewards through dialogue boxes and menus. It is function 13 of 89 in asm/main_0203CAF0.s, so extract_function.py splits rather than merges: the 76 functions after it move to asm/main_0203EFD4.s, the function lands in src/main_0203D538.c with include/main_0203D538.h, and main.lsf lists both new objects where it listed one. src/overlay_24_init.c declared sub_0203D538 itself, with a live call site in a switch. That extern is removed and the file now includes the new header. Case order is source order and is not ascending - two contiguous runs are swapped (32,33,34 before 30,31; and 52..57 before 45..51), read off the jump table. Every case ends `break` with a single `return 0` after the switch, because the target's exit block itself materialises the value: a `return 0` per case makes MWCC materialise r0 at each of 77 sites and, worse, de-predicates the short blocks above them. case 76 keeps its `return 1`, which is how the target jumps past that shared `mov r0, #0`. The nine function-scope locals are declared buffer-first then the five struct item in reverse case order, because MWCC gives the first-declared local the highest stack address and the target wants the buffer at sp+0x22. That ordering costs no instructions, so it shows up only as a wrong offset at every stack access - not as a length difference. struct unk_020AFE74 is a placeholder for the 0x3C0-byte state struct, with field_0x<off> members and two u8 filler ranges this function never touches; it cannot be honestly typed from one caller. The 19 callees with no declaration anywhere are declared extern in the .c with prototypes read off their own asm, and two of them - sub_02046C78 and sub_02046D20 - take no arguments, contradicting src/main_020663C8.c. Region handling: 35 message ids carry a uniform +0x21D4 under JAPAN via one file-scope offset macro; one id at 0x2CC shifts by +0x2D20 instead and needs its own ifdef; StrncpySimple becomes the two-argument StrcpySimple; and JAPAN omits case 74's item fetch, its name formatting and its early-exit guard, which is what removes a struct item local and takes the frame from 0x11C to 0x114. EUROPE is byte-identical to NORTH_AMERICA - there is no EUROPE directive anywhere in this function. Authored by Claude (Opus 5) under human direction. Confirmed by matching builds of 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> |
||
|
|
d814f8d017 |
Decomp ApplyItemEffect; replace its stale extern with the new header
ApplyItemEffect (0x0231B68C, 1310 instructions in US, 1312 in EU) is the thrown/eaten item dispatcher: an item-catcher preamble, the sticky-item block, and then one switch (item->id) over a 183-entry jump table with 85 distinct case bodies, a shared tail that walks APPLES_AND_BERRIES_ITEM_IDS, and EnemyEvolution. It is the last of ten functions in asm/overlay_29_0231B33C.s and the next object in main.lsf is src/overlay_29_0231CBC8.o, so extract_function.py merges rather than splits and main.lsf is unchanged. src/dungeon_projectile_throw.c declared ApplyItemEffect itself, with a live call site. That extern is removed and the file now includes the new header instead. It is a landed, already-matching object and parameters 1-3 are exactly where a wrong spelling would surface, so its rebuild in all three regions is a check on the signature rather than tidying. case ITEM_NOTHING is written explicitly above default even though the jump table sends id 0 there. The dispatch is cmp r0,#0 / addge pc,pc,r0,lsl #2 with no rebase, and a survey of all 786 such dispatches in asm/ shows MWCC's table spans the minimum to maximum LABELLED case: 104 of the 105 rebased tables have a real case at index 0, rebases occur for offsets as small as 3, yet 40 tables have 3-7 leading default entries un-rebased and 82 have trailing default entries, which padding cannot explain. Leading and trailing default entries are therefore explicit case labels sharing default's body. The category-5/10 test that skips the switch is an if/else whose else arm is the entire switch; both arms fall into the shared tail. Case emission order is source order and is not ascending (8 before 7, 77 before 74, 136 before 113, 182 before 104, default last). The 41 callees that are still asm are declared extern in the .c with prototypes read off their own asm, as the sibling files do, and so are the 28 rodata data symbols - const, with ov10_022C4864 as s32 where the other 25 scalars are s16, which is what makes its load a 32-bit ldr. Two prototypes deliberately differ from pmdsky-debug: ApplyKeyEffect takes one parameter, not two, and CalcDamageFixedNoCategory's fifth parameter points at a one-byte object, not a struct damage_data. Region handling: seven message ids are file-scope defines at US - 0x2C1 under JAPAN, and one EU-only call to ov29_022FB920 sits inside an ifdef EUROPE with its prototype. The JP fork of the exclusive_item_effect_flags offset needs nothing - the header already models the 4-byte JP struct monster shrink. Authored by Claude (Opus 5) under human direction. Confirmed by matching builds of 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> |
||
|
|
d387d4e273 |
Decomp ActivateEndOfTurnEffects; monster::bide_move_id is a 2-byte enum move_id
ActivateEndOfTurnEffects (0x0230FC24, 1235 instructions in US) is the per-turn status tick: the warp-scarf counter, the leader's belly and hunger messages, weather damage, Shed Skin and Hydration, the burn, poison, bad-poison, constriction, wrap, ingrain, curse and leech-seed damage countdowns, perish song and bide. It is the last of five functions in asm/overlay_29_0230F9A4.s and the next object in main.lsf is src/overlay_29_02311010.o, so extract_function.py merges rather than splits and main.lsf is unchanged. struct monster declared 0xAC as u8 bide_move_id plus u8 field_0xad. Retail accesses it with ldrh/strh and stores 0x165 = MOVE_BIDE_UNLEASH, which does not fit in a byte; enum move_id runs to 558, so -enum min sizes it to two bytes - the width struct move's own enum move_id id at 0x2 already has. The field becomes enum move_id and absorbs field_0xad. The struct size and every later offset are unchanged, no other source reads either member, and InitMove already takes enum move_id so no cast is needed. This deviates from pmdsky-debug's u8; the reasoning note linked from the PR has the evidence. The 29 callees that are still asm are declared extern in the .c with prototypes read off their own asm, as the sibling files do, and so are the 24 data symbols - const on the read-only rodata ones, which is what places their loads correctly. Region handling: the sound-effect guard in the hunger block is a genuine three-way fork, EU calling ov29_022E34A8_EU where JP omits the end_floor_no_death_check_flag test that US performs, and nine message ids are file-scope defines at US - 0x2C0 under JAPAN. The JP struct and dungeon offset shifts are absorbed by the headers with no directive. Locals are generic and declared at function scope. That is not cosmetic: the allocator's unit is the coalesced web, and the function-scope declaration list is the only thing that orders it, so the declaration order is what reproduces retail's register assignment. Authored by Claude (Opus 5) under human direction. Confirmed by matching builds of 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> |
||
|
|
33d90d0f8d |
Decomp the fixed-point helper cluster at the end of main_020504BC.s
sub_02050EBC, SubFixedPoint, sub_02050F78, sub_02050FF8 and
BinToDecFixedPoint are the last five functions in asm/main_020504BC.s and
all operate on struct fixed_point (106 instructions). The next object in
main.lsf is src/number_util.o, which already holds their sibling
CeilFixedPoint, so extract_function.py merges rather than splits and
main.lsf is unchanged. They are landed in reverse address order so each
prepends above the last, leaving number_util.c in ascending address order
with CeilFixedPoint last.
sub_02050EBC and sub_02050F78 keep their sub_<addr> names - this is
decompilation, not identification.
A 4-byte struct fixed_point is passed and returned by value in r0, packed
as integer | fractional << 16. The stmdb sp!, {r0, r1, r2, r3} at entry is
MWCC giving the argument registers stack homes so a by-value struct
parameter can be addressed, and writing to the parameter reuses that home,
which is why SubFixedPoint and sub_02050EBC modify their first argument
and return it. The caller-side sub rX, sp, #4 idiom around these calls is
compiler-generated, not a source construct: src/dungeon_ai_movement.c
already emits it from a plain CeilFixedPoint(pokemon_info->belly).
None of the five blocks carries a region directive, so one source serves
all three regions.
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>
|
||
|
|
9097cad39d |
Use generic local names in the five functions landed since 51c365db
CalcDamage, CalcTypeBasedDamageEffects, ApplyDamage, ApplyDamageAndEffects and ov11_022ED69C had locals named after what the decompiler inferred them to mean. A local's meaning is not something the matching build can check, so every such name is replaced by a type-derived generic one numbered in declaration order: fixed-point temporaries fp1.., monster pointers mon1.., scalar values v1.., bool8 flags f1.., pointers p1.. / ent1.. / item1.. / ls1.., arrays arr / buf. Names that were already generic (i, j, k, n, result) or are simply the type's own name (diag, weather, tile, member, entry, spec) are unchanged, and so are all parameters, whose names upstream syncs from pmdsky-debug. Declaration order is untouched; only identifiers change, so no object changes. Authored by Claude (Fable 5.1) under human direction. Confirmed by matching builds of all three regions after the rename: 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 Fable 5.1 <noreply@anthropic.com> |
||
|
|
7653350896 |
Decomp CalcDamage; damage_calc_diag's move_category is 4 bytes, its modifiers unsigned
CalcDamage (0x0230BBAC, 1290 instructions) is the damage formula: stat
stages, item/ability/IQ-skill modifiers, the fixed-point base formula,
CalcTypeBasedDamageEffects, critical hits, Reflect/Light Screen and the
final multipliers, with its diagnostics in DUNGEON_PTR->last_damage_calc.
It is the first of 26 functions in asm/overlay_29_0230BBAC.s and a rodata
object precedes that object in main.lsf, so extract_function.py splits
rather than merges: the function lands in src/overlay_29_0230BBAC.c with
include/overlay_29_0230BBAC.h, the other 25 move to
asm/overlay_29_0230D088.{s,inc}, and main.lsf lists both objects where it
listed one.
struct damage_calc_diag modelled move_category as a 1-byte enum plus
field_0x5/0x6/0x7 padding (3fc6d8bd). Retail writes that field with a
4-byte str (0x0230BDC8) and reads the eight modifier bytes at 0x30..0x37
unsigned (ldrb at 24 sites), so move_category becomes s32 - the struct
stays 0x54 bytes - and the modifiers become u8 (they were s8). No other
source in the tree reads these members. Both deviate from pmdsky-debug's
declarations; the reasoning note linked from the PR has the evidence.
Region handling follows the neighbouring files: six
DefenderAbilityIsActive__0230A940 calls take three arguments under JAPAN,
and message ids C53/C54/C55/C57/C58 and DC1 are file-scope defines at
US - 0x2C1 under JAPAN. One difference is real source: the defense-side
apparent_id 0x211/0x218 checks compare the attacker's apparent_id under
JAPAN (the JP-only ldrsh r1, [r6, #4]). EU is identical to US.
The 17 callees that are still asm are declared extern in the .c with
prototypes read off their own asm, as the sibling files do. The spelling
of the ability-multiply block (an s32 calc[2] local, two temps and three
volatile s32 * pointers) is match-derived, each element removing one
measured compiler obstacle; the reasoning note explains it.
Authored by Claude (Fable 5.1) under human direction. Confirmed by
matching builds of all three regions: build/pmdsky.us/pmdsky.us.nds: OK,
build/pmdsky.eu/pmdsky.eu.nds: OK, build/pmdsky.jp/pmdsky.jp.nds: OK,
each also passing main.sha1, filesystem.sha1 and arm7.sha1.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
||
|
|
38aa265d9d |
Decomp CalcTypeBasedDamageEffects; pad damage_calc_diag to its real layout
CalcTypeBasedDamageEffects (0x0230AD04, 676 instructions) applies every
type-, ability-, weather- and status-based multiplier to a damage
calculation. It merges into src/type_effectiveness.c, which already held
its callee GetTypeMatchup, so asm/overlay_29_0230AD04.{s,inc} are removed
and main.lsf loses that object with no new object added.
struct damage_calc_diag modelled move_type as a 1-byte enum plus explicit
field_0x1/0x2/0x3 padding, but gave move_category no such padding, so
every member from move_indiv_type_matchups (0x8) to attacker_level (0x16)
compiled below the offset its own comment states. Downstream alignment
before damage_calc re-absorbed the drift, so the struct still totalled
0x54 and no build caught it; the two existing users in the tree both sit
past the re-convergence point. asm/overlay_29_022E0378.s writes 0x188 and
asm/overlay_29_022E335C.s reads 0x184/0x188 with word accesses, so both
fields are four bytes in retail. Adding field_0x5/0x6/0x7 is byte-neutral
for the existing tree.
include/type_effectiveness.h gains overlay_29_02308FBC.h, which defines
the struct unk_02308FE0 its new declaration names.
Region handling follows the neighbouring files: six
DefenderAbilityIsActive__0230A940 calls take three arguments under JAPAN
and four elsewhere, and five message ids are file-scope defines at
US - 0x2C1 under JAPAN. EU is identical to US - the original asm block
carries no EUROPE directive at all.
Authored by Claude (Opus 5) under human direction. Confirmed by matching
builds of all three regions: build/pmdsky.us/pmdsky.us.nds: OK,
build/pmdsky.eu/pmdsky.eu.nds: OK, build/pmdsky.jp/pmdsky.jp.nds: OK,
each also passing main.sha1 and filesystem.sha1.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
5f96316f71 |
Decomp ApplyDamageAndEffects; ApplyDamage's damage source is signed 16-bit
ApplyDamageAndEffects (617 instructions, overlay 29 at 0x0230863C) lands in src/overlay_29_02308FBC.c beside ApplyDamage, with all three regions matching. JAPAN differs in eleven places: ten DefenderAbilityIsActive__0230A940 calls drop their fourth argument (the header already declares both forms), and the counter-damage message id is US - 0x2C1, added as MESSAGE_C3F alongside the existing per-region defines. EUROPE is byte-identical to US. ApplyDamage's sixth parameter changes from enum damage_source_non_move to s16. The caller loads it with ldrsh and passes it in a register; the enum is all-positive so -enum min makes it unsigned 2-byte, which emits ldrh there. s16 scores 0 on both functions and all three ROMs still match, so this is a correction to the type rather than a change in behaviour. New in this commit: struct unk_023535DC for the exclusive-item effect table at ov29_023535DC (16-byte stride: effect id, argument, handler), and externs for the ten ov10_022C* activation-chance globals and six overlay callees. Three constructs are colouring devices rather than recovered source and should be read as stand-ins: a (u32) cast on the final return, a (s16) cast on the counter-attack loop's damage-source argument, and *(u8 *)effect as the effect loop's condition. Each is plain C, and each is load-bearing for the match. Authored by Claude (Opus 5 and Fable 5) under human direction. Confirmed by matching builds of all three ROMs: build/pmdsky.us/pmdsky.us.nds: OK, build/pmdsky.eu/pmdsky.eu.nds: OK, build/pmdsky.jp/pmdsky.jp.nds: OK -- each also passing main.sha1, so the ARM9 binaries match and not only the packaged ROMs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e0f7191722 |
ApplyDamage: match the EU and JP builds
Follow-up to ff65ac0e, which decompiled the US branch only. One source now
matches all three regions:
build/pmdsky.us/pmdsky.us.nds: OK
build/pmdsky.eu/pmdsky.eu.nds: OK
build/pmdsky.jp/pmdsky.jp.nds: OK
JAPAN, five source differences:
- DefenderAbilityIsActive__0230A940 takes three arguments, not four, at six
call sites. include/overlay_29_0230A994.h already declares this, so the JP
build failed to compile rather than to match.
- every message id is US - 0x2C1. Kept as region-conditional #defines at file
scope, following src/dungeon_ai.c.
- no UpdateStatusIconFlags call before the HP check.
- no end_floor_no_death_check_flag guard on the revival-item path.
- in the reviver-seed block, no ov29_022FBD24; instead ov29_02307DC0 after the
curse handling.
EUROPE, one behavioural difference: the last arm of the defeat-message ladder
records a flag instead of logging, and the message is emitted later at three
points - the reviver-seed path, the revival-item path, and their else. The two
revival paths log from a different table.
That table is four bytes that exist only in the EUROPE branch of
asm/overlay_29_rodata_02352A6C.s, immediately after ov29_02353218 and carrying
no symbol; the extractor could only render both as raw addresses (0x02353E44 and
0x02353E40). This commit labels it. The label and .global add no bytes, and the
EU checksum is what confirms both references resolve where intended - had either
been wrong, pmdsky.eu.nds would not match.
The name ov29_02353E44 is keyed to the symbol's EUROPE address, which breaks the
file's convention of naming by US address. There is no US address to use: the
data does not exist in that build.
One change was needed for the EU register allocation and is byte-neutral for the
other two builds: `dmon` is now assigned after the wild-enemy test rather than
before it, with that test reading through defender->info. Introducing the
variable later flips which web the allocator colours first and unwinds a
whole-function rotation of three callee-saved registers.
Authored by Claude (Opus 5) under human direction. Confirmed by matching builds
of all three regions.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
eb0db73b1f |
Decomp ApplyDamage; fix a message-id parameter type and three field types
ApplyDamage (overlay 29, 0x02308FE0). asm/overlay_29_02308FE0.s and its .inc are removed and the object drops out of main.lsf; the function merges into src/overlay_29_02308FBC.c alongside EntityIsValid__02308FBC. Types added: struct unk_02308FE0 (the damage-data argument, in the function's header), struct unk_023528A4 and struct unk_022C593C (element types for TYPE_DAMAGE_NEGATING_EXCLUSIVE_ITEM_EFFECTS and ov10_022C593C, local to the .c). Field types corrected, each required by the match: struct monster::bide_damage_tally u32 -> s32 (clamped with strgt) struct monster::field_0x168 / field_0x169 -> s16 field_0x168 (read ldrsh) struct dungeon_generation_info::music_table_idx u16 -> s16 (read ldrsh) TalkToSecretBazaarNpcStandard, ov29_022F0618, TalkToSecretBazaarNpcWithYesNoMenu and the TalkToSecretBazaarNpc extern take a message id in their first parameter, not a struct entity *. Every caller loads a small constant into r0 - 0xC6B from ApplyDamage, 0xF32/0xF4A/0xF4B/0xF4C in asm/overlay_29_02344178.s. The three tree functions are one-line forwarders, so their parameter types were unconstrained; ApplyDamage is the first C caller. Two things a reviewer should weigh. DUNGEON_PTR is declared scalar here (extern struct dungeon *DUNGEON_PTR;) rather than the *DUNGEON_PTR[] idiom the other files use - the array form lets MWCC CSE the load and costs three instructions. And one read is qualified volatile (*(volatile u8 *)&dmon->curse_class_status.curse) to reproduce a reload retail performs with no intervening call; it is standard C and the ROM matches, but it is a stand-in rather than recovered source, and a struct curse_class_status * local gets to within one instruction without it. Only the US branch is decompiled; the original block carries 50 preprocessor directives including two wholesale #ifdef EUROPE duplications. Authored by Claude (Opus 5) under human direction. Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK (main.sha1 passes, so the ARM9 binary matches and not only the packaged ROM). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c1a61413d6 |
Decomp ov11_022ED69C; correct BmaHeader field signedness
Decompiles ov11_022ED69C (410 instructions) out of asm/overlay_11_022ECD24.s. The function was first in that file, so the remainder splits to asm/overlay_11_022EDD14.s and main.lsf gains src/overlay_11_022ED69C.o ahead of it. include/ground_bg.h: - MapRender 0x1C -> 0x54, adding unk1C/unk24/unk2C (two pointers each) and a 0x20 filler. This consumes GroundBg::fillerForNow2[112] exactly: 0x210 + 2*0x54 == 0x2B8, so no offset after it moves, and ground_bg.c only ever uses mapRender[0]. - GroundBg::unk1FC: four unreferenced u8 -> one s32. - BmaHeader::numLayers/hasDataLayer/hasCollision: u16 -> s16. Retail reads these with ldrsh; the u16 declaration emitted ldrh and produced three wrong bytes in OVY_11.sbin. This function is their only reader in the tree -- every other use is a strh, identical either way -- so no other object changes. - RGB_Array, the UnkStruct_2324CBC family, the three palette helpers, ov11_02320C18 and ov11_02320BF4/BE8 move here from src/ground_bg.c, which now includes them rather than redeclaring them. asm/overlay_11_022ECD24_data.s has its .include repointed at the .inc that survived the split; extract_function.py deletes the old one without knowing about sibling objects in the same address range. ov11_022EE9B0 and ov11_022EE8CC are still asm and are declared provisionally in include/overlay_11_022ED69C.h from their call sites. 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> |
||
|
|
a3d641227a |
Merge pull request #299 from AnonymousRandomPerson/main
Some checks failed
build / build (push) Has been cancelled
Synced from pmdsky-debug |
||
|
|
c5b2361599 | Synced from pmdsky-debug | ||
|
|
88b7534029 | Synced from pmdsky-debug | ||
|
|
c0b9172888 |
Merge pull request #298 from darkruss48/main
Some checks failed
build / build (push) Has been cancelled
Decomp 13 functions, emptying six asm files |
||
|
|
4c3524cdeb | Address review | ||
|
|
0e4b52cea5 | Decomp 13 functions, emptying six asm files | ||
|
|
c313f0090e |
Merge pull request #297 from darkruss48/main
Some checks failed
build / build (push) Has been cancelled
Decomp 8 functions, emptying seven asm files |
||
|
|
a3fef4c1ac |
Clean up comments in mai_020527A8.c file
comments cleared |
||
|
|
4558d17ea1 |
Clean up comments in sub_0200EB64 function
comments cleared |
||
|
|
2c2c5c2a04 |
Decomp 8 functions, emptying seven asm files
Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. |
||
|
|
02e838c934 |
Merge pull request #296 from AnonymousRandomPerson/main
Some checks failed
build / build (push) Has been cancelled
Synced from pmdsky-debug |
||
|
|
db6076849a | Rename quicksave symbols according to comments |