diff --git a/config/arm9/delinks.txt b/config/arm9/delinks.txt index 597e26cd0..935bd5e74 100644 --- a/config/arm9/delinks.txt +++ b/config/arm9/delinks.txt @@ -135,7 +135,7 @@ src/func_020071e0.c: complete .text start:0x020071e0 end:0x020072c0 -src/func_020072c0.c: +src/_ZN7Vector3D1Ev.cpp: complete .text start:0x020072c0 end:0x020072c4 @@ -1201,7 +1201,7 @@ src/_ZN5ActorC1Ev.cpp: complete .text start:0x020113c0 end:0x02011508 -src/func_02011508.c: +src/_ZN8Vector3sD1Ev.cpp: complete .text start:0x02011508 end:0x0201150c diff --git a/config/arm9/overlays/ov002/delinks.txt b/config/arm9/overlays/ov002/delinks.txt index 436eb8c61..aed4b0857 100644 --- a/config/arm9/overlays/ov002/delinks.txt +++ b/config/arm9/overlays/ov002/delinks.txt @@ -115,11 +115,11 @@ src/_ZN5EnemyD2Ev.c: complete .text start:0x020aed18 end:0x020aed3c -src/_ZN5EnemyD0Ev.c: +src/_ZN5EnemyD0Ev.cpp: complete .text start:0x020aed3c end:0x020aed74 -src/_ZN5EnemyD1Ev.c: +src/_ZN5EnemyD1Ev.cpp: complete .text start:0x020aed74 end:0x020aed98 @@ -3248,6 +3248,7 @@ src/func_ov002_020d6998.cpp: .text start:0x020d6998 end:0x020d6c60 src/func_ov002_020d6c60.cpp: + complete .text start:0x020d6c60 end:0x020d6dac src/func_ov002_020d6dac.c: @@ -4651,7 +4652,7 @@ src/_ZN8PlatformD1Ev.cpp: complete .text start:0x020ee42c end:0x020ee464 -src/_ZN8PlatformD0Ev.c: +src/_ZN8PlatformD0Ev.cpp: complete .text start:0x020ee464 end:0x020ee4b0 diff --git a/config/arm9/overlays/ov002/symbols.txt b/config/arm9/overlays/ov002/symbols.txt index 4e9c25de3..ca01c5e74 100644 --- a/config/arm9/overlays/ov002/symbols.txt +++ b/config/arm9/overlays/ov002/symbols.txt @@ -1667,6 +1667,7 @@ data_ov002_021081b8 kind:data(any) addr:0x021081b8 _ZTI12dEnemyBase_c kind:data(any) addr:0x021081c0 _ZTS12dEnemyBase_c kind:data(any) addr:0x021081cc data_ov002_021081e4 kind:data(any) addr:0x021081e4 +_ZTV5Enemy kind:data(any) addr:0x021081e4 _ZTI11dCapEnemy_c kind:data(any) addr:0x02108260 _ZTS11dCapEnemy_c kind:data(any) addr:0x0210826c data_ov002_02108284 kind:data(any) addr:0x02108284 @@ -2237,6 +2238,7 @@ _ZTI16dPathLiftActor_c kind:data(any) addr:0x0210af0c _ZTS16dPathLiftActor_c kind:data(any) addr:0x0210af18 data_ov002_0210af2c kind:data(any) addr:0x0210af2c data_ov002_0210af70 kind:data(any) addr:0x0210af70 +_ZTV8PathLift kind:data(any) addr:0x0210af70 _ZTS9daSCoin_c kind:data(any) addr:0x0210aff4 _ZTI9daSCoin_c kind:data(any) addr:0x0210b000 InvisibleSecret_SpawnInfo kind:data(any) addr:0x0210b00c diff --git a/config/arm9/overlays/ov014/delinks.txt b/config/arm9/overlays/ov014/delinks.txt index 62cf8a044..7240399da 100644 --- a/config/arm9/overlays/ov014/delinks.txt +++ b/config/arm9/overlays/ov014/delinks.txt @@ -27,7 +27,7 @@ src/ShutterBob_Spawn.c: complete .text start:0x021112cc end:0x02111308 -src/_ZN10ChainChompD1Ev.c: +src/_ZN10ChainChompD1Ev.cpp: complete .text start:0x02111308 end:0x021113bc diff --git a/config/arm9/overlays/ov016/delinks.txt b/config/arm9/overlays/ov016/delinks.txt index 0d53fe736..ff819c0f4 100644 --- a/config/arm9/overlays/ov016/delinks.txt +++ b/config/arm9/overlays/ov016/delinks.txt @@ -4,7 +4,7 @@ .ctor start:0x02113abc end:0x02113ad0 kind:rodata align:4 .data start:0x02113ae0 end:0x02114d20 kind:data align:32 .bss start:0x02114d20 end:0x02114ea0 kind:bss align:32 -src/_ZN5UnagiD1Ev.c: +src/_ZN5UnagiD1Ev.cpp: complete .text start:0x021111a0 end:0x02111208 diff --git a/config/arm9/overlays/ov034/delinks.txt b/config/arm9/overlays/ov034/delinks.txt index 9895b7c65..283d69490 100644 --- a/config/arm9/overlays/ov034/delinks.txt +++ b/config/arm9/overlays/ov034/delinks.txt @@ -4,11 +4,11 @@ .ctor start:0x02114078 end:0x0211407c kind:rodata align:4 .data start:0x02114080 end:0x02114620 kind:data align:32 .bss start:0x02114620 end:0x021148e0 kind:bss align:32 -src/_ZN7WigglerD1Ev.c: +src/_ZN7WigglerD1Ev.cpp: complete .text start:0x021111a0 end:0x021112b0 -src/_ZN7WigglerD0Ev.c: +src/_ZN7WigglerD0Ev.cpp: complete .text start:0x021112b0 end:0x021113d4 diff --git a/config/arm9/overlays/ov073/delinks.txt b/config/arm9/overlays/ov073/delinks.txt index d838dcf1c..4a4794a66 100644 --- a/config/arm9/overlays/ov073/delinks.txt +++ b/config/arm9/overlays/ov073/delinks.txt @@ -3,11 +3,11 @@ .ctor start:0x02122f34 end:0x02122f3c kind:rodata align:4 .data start:0x02122f40 end:0x02123280 kind:data align:32 .bss start:0x02123280 end:0x021234e0 kind:bss align:32 -src/_ZN11ChiefChillyD1Ev.c: +src/_ZN11ChiefChillyD1Ev.cpp: complete .text start:0x0211f000 end:0x0211f098 -src/_ZN11ChiefChillyD0Ev.c: +src/_ZN11ChiefChillyD0Ev.cpp: complete .text start:0x0211f098 end:0x0211f144 diff --git a/config/arm9/overlays/ov074/delinks.txt b/config/arm9/overlays/ov074/delinks.txt index df8ad3767..41091ea61 100644 --- a/config/arm9/overlays/ov074/delinks.txt +++ b/config/arm9/overlays/ov074/delinks.txt @@ -4,7 +4,7 @@ .ctor start:0x02122d70 end:0x02122d74 kind:rodata align:4 .data start:0x02122d80 end:0x02122fe0 kind:data align:32 .bss start:0x02122fe0 end:0x021231a0 kind:bss align:32 -src/_ZN8GoombossD1Ev.c: +src/_ZN8GoombossD1Ev.cpp: complete .text start:0x0211f000 end:0x0211f0a0 diff --git a/config/arm9/overlays/ov091/delinks.txt b/config/arm9/overlays/ov091/delinks.txt index 9427c9af1..27678018b 100644 --- a/config/arm9/overlays/ov091/delinks.txt +++ b/config/arm9/overlays/ov091/delinks.txt @@ -294,9 +294,6 @@ src/_ZN5StumpD0Ev.c: complete .text start:0x021339a8 end:0x021339fc -src/func_ov091_021339fc.c: - .text start:0x021339fc end:0x02133c6c - src/func_ov091_02133c6c.cpp: complete .text start:0x02133c6c end:0x02133d1c diff --git a/config/arm9/symbols.txt b/config/arm9/symbols.txt index a0e494bd6..3f1a22081 100644 --- a/config/arm9/symbols.txt +++ b/config/arm9/symbols.txt @@ -51,7 +51,8 @@ _ZN6CameraD0Ev kind:function(arm,size=0x50) addr:0x02007098 func_020070e8 kind:function(arm,size=0xc0) addr:0x020070e8 func_020071a8 kind:function(arm,size=0x38) addr:0x020071a8 func_020071e0 kind:function(arm,size=0xe0) addr:0x020071e0 -func_020072c0 kind:function(arm,size=0x4) addr:0x020072c0 +_ZN7Vector3D1Ev kind:function(arm,size=0x4) addr:0x020072c0 +func_020072c0 kind:function(arm,size=0x0) addr:0x020072c0 func_020072c4 kind:function(arm,size=0xdc) addr:0x020072c4 func_020073a0 kind:function(arm,size=0x74) addr:0x020073a0 func_02007414 kind:function(arm,size=0x3c) addr:0x02007414 @@ -319,7 +320,8 @@ _ZN5ActorD2Ev kind:function(arm,size=0x4c) addr:0x020112c8 _ZN5ActorD0Ev kind:function(arm,size=0x60) addr:0x02011314 _ZN5ActorD1Ev kind:function(arm,size=0x4c) addr:0x02011374 _ZN5ActorC1Ev kind:function(arm,size=0x148) addr:0x020113c0 -func_02011508 kind:function(arm,size=0x4) addr:0x02011508 +_ZN8Vector3sD1Ev kind:function(arm,size=0x4) addr:0x02011508 +func_02011508 kind:function(arm,size=0x0) addr:0x02011508 _ZN5ActorC2Ev kind:function(arm,size=0x148) addr:0x0201150c func_02011654 kind:function(arm,size=0x44) addr:0x02011654 func_02011698 kind:function(arm,size=0x2c) addr:0x02011698 diff --git a/include/Actor.h b/include/Actor.h index 75d36f6f4..e3af15149 100644 --- a/include/Actor.h +++ b/include/Actor.h @@ -112,9 +112,14 @@ struct Actor : ActorDerived { s32 mHorzSpeed; /* 0x098 */ s32 mVertAccel; /* 0x09c -- fix12, negative (gravity) */ s32 mTerminalVelocity; /* 0x0a0 -- fix12, negative */ - u8 pad_0a4[0x4]; /* likely the same physics block; unproven */ + /* 0x0a4 and 0x0ac were padding "likely the same physics block; unproven". + They are real, and Enemy is the evidence: its generated header declared + both as s32 and its sources read them, so once `Enemy : Actor` they have + to exist here. Still unnamed -- what they mean is not evidenced, only + that they are Actor's and four bytes wide. */ + s32 unk_0a4; /* 0x0a4 */ s32 mVertSpeed; /* 0x0a8 */ - u8 pad_0ac[0x4]; /* likely the same physics block; unproven */ + s32 unk_0ac; /* 0x0ac */ u32 mFlags; /* 0x0b0 -- bit 0x10000 suppresses behaviour */ s32 unk_0b4; /* 0x0b4 */ s32 unk_0b8; /* 0x0b8 -- clip radius; 0 skips the camera transform */ diff --git a/include/Animation.h b/include/Animation.h index 4f38d9f1c..acfef8257 100644 --- a/include/Animation.h +++ b/include/Animation.h @@ -43,6 +43,8 @@ struct BCA_File; struct SharedFilePtr; +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct Animation { /* 0x00 is the vptr, placed implicitly by the first virtual declaration. */ u32 numFramesAndFlags; /* 0x04 - count in bits 0..29, loop flags in 30..31 */ @@ -66,6 +68,23 @@ struct Animation { /* --- static --- */ static char *LoadFile(SharedFilePtr &ptr); static void UpdateFileOffsets(BCA_File &file); + + /* WHAT LETS A REAL `~Class()` REPRODUCE THE ROM'S DELETING DESTRUCTOR. + The compiler generates D0 as "run the destructor body, then call operator + delete on the class". Without this it emits the global `_ZdlPv`, which + exists nowhere in this image, and the D0 comes out one relocated word + different from the ROM -- a difference build_pin.verify CANNOT SEE, + because it wildcards relocated words. Only the link catches it. + + This family deallocates through Memory::operator_delete2, not the actor + heap: every D0 below ends with a call to 0x0203cbcc. Actor's copy of this + member calls Memory::Deallocate instead, which is why each needs its own. + + Inline, and in the IMMEDIATE base -- mwcc inlines it only when it finds it + in the class or one level up, as include/Actor.h records. No layout + effect: a non-virtual inline member adds no field and no vtable slot. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; typedef char Animation_size_must_be_0x10[sizeof(Animation) == 0x10 ? 1 : -1]; diff --git a/include/ArrowSignRight.h b/include/ArrowSignRight.h index 944447b95..1d3602ffe 100644 --- a/include/ArrowSignRight.h +++ b/include/ArrowSignRight.h @@ -1,13 +1,45 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class ArrowSignRight: 6 matched functions, 7 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef ARROWSIGNRIGHT_H #define ARROWSIGNRIGHT_H + #include "types.h" -#include "Model.h" + +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" #include "ShadowModel.h" +struct ArrowSignRight : Platform { + u8 pad_31e[0x2]; + ShadowModel mShadowModel; /* 0x320 */ + u8 unk_348; /* 0x348 */ + u8 pad_349[0x33]; + u8 unk_37c; /* 0x37c */ + + /* --- vtable --- */ + virtual ~ArrowSignRight(); + + int Behavior(); + int CleanupResources(); + int Render(); +}; + +typedef char ArrowSignRight_size_must_be_0x380[sizeof(ArrowSignRight) == 0x380 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct ArrowSignRight { u8 pad_000[0xc]; u16 unk_00c; /* 0x00c */ @@ -26,12 +58,8 @@ struct ArrowSignRight { u8 unk_348; /* 0x348 */ u8 pad_349[0x33]; u8 unk_37c; /* 0x37c */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* ARROWSIGNRIGHT_H */ diff --git a/include/BigBrickBlock.h b/include/BigBrickBlock.h index 223e48e73..6de21c7b3 100644 --- a/include/BigBrickBlock.h +++ b/include/BigBrickBlock.h @@ -2,18 +2,12 @@ #define BIGBRICKBLOCK_H #include "types.h" -#include "Platform.h" /* Derives from Platform: the destructor stores this class's vtable, then * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and - * the Model at 0xd4 before chaining to Actor. All three are Platform's. + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. * Everything this header used to restate below 0x31e was Actor's and - * Platform's. - * - * THE FIELDS AT 0x31e/0x31f ARE IN PLATFORM'S TAIL PADDING. Platform's last - * field ends at 0x31e and its size rounds to 0x320; the Itanium ABI lets a - * derived class use a non-POD base's tail padding, and the ROM does. The bytes - * settle it -- code here reads this+0x31e and reproduces. + * Platform's, and is inherited now. * * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it * is not independent evidence about the ROM. @@ -21,10 +15,12 @@ #ifdef __cplusplus +#include "Platform.h" + struct BigBrickBlock : Platform { - u8 unk_31e; /* 0x31e - in Platform's tail padding */ - u8 unk_31f; /* 0x31f */ - u8 mEventID; /* 0x320 */ + u8 unk_31e; /* 0x31e */ + u8 unk_31f; /* 0x31f */ + u8 mEventID; /* 0x320 */ u8 pad_321[0x3]; Actor *mSwitch; /* 0x324 */ @@ -39,6 +35,32 @@ struct BigBrickBlock : Platform { typedef char BigBrickBlock_size_must_be_0x328[sizeof(BigBrickBlock) == 0x328 ? 1 : -1]; +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ +struct BigBrickBlock { + u8 pad_000[0xc]; + u16 mActorId; /* 0x00c */ + u8 pad_00e[0xc6]; + /* Model member, named by the class's own destructor calling + Model's D1 at +0x0d4 -- a relocation the ROM build + checks. Was a u8 marker. [_ZN13BigBrickBlockD1Ev.c] */ + Model mModel; /* 0x0d4 */ + u8 mMeshCollider; /* 0x124 */ + u8 pad_125[0x1f9]; + u8 unk_31e; /* 0x31e */ + u8 unk_31f; /* 0x31f */ + u8 mEventID; /* 0x320 */ + u8 pad_321[0x3]; + /* Actor * -- the ROM loads this WORD and passes it to _ZN5Actor15FindWithActorIDEjPS_ + as that function's `this`, which is an object address, so the word is a Actor *. It + says nothing about the rest of the marker's span, which stays explicit padding. Was + a u8 marker. */ + Actor *mSwitch; /* 0x324 */ +}; + #endif /* __cplusplus */ #endif /* BIGBRICKBLOCK_H */ diff --git a/include/BlendModelAnim.h b/include/BlendModelAnim.h index 4d4046eb2..9e3cf0d6e 100644 --- a/include/BlendModelAnim.h +++ b/include/BlendModelAnim.h @@ -24,6 +24,8 @@ #ifdef __cplusplus +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct BlendModelAnim : ModelAnim { Fix12i blendWeight; /* 0x64 - 0x1000 is 1.0 */ Fix12i blendStep; /* 0x68 - per-frame increment */ @@ -41,6 +43,16 @@ struct BlendModelAnim : ModelAnim { void Advance(); void SetAnim(BCA_File &animFile, int numBlendFrames, int flags, Fix12 speed, u16 startFrame); /* free function, wall 6az */ + + /* ITS OWN, TO RESOLVE AN AMBIGUITY MULTIPLE INHERITANCE CREATES. ModelAnim + derives from Model (so ModelBase) and from Animation, and both bases + declare operator delete, so an inherited one is "ambiguous access to + name found: ModelBase::operator delete and Animation::operator delete". + Declaring it here picks the same deallocator both bases name, and also + satisfies the rule in include/Actor.h that mwcc only inlines the member + when it is in the class or its immediate base. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; typedef char BlendModelAnim_size_must_be_0x70[sizeof(BlendModelAnim) == 0x70 ? 1 : -1]; diff --git a/include/BlueCoinSwitch.h b/include/BlueCoinSwitch.h index e54b4e5e1..2d2260cef 100644 --- a/include/BlueCoinSwitch.h +++ b/include/BlueCoinSwitch.h @@ -1,24 +1,48 @@ -/* Hand-written from matched-function evidence: - * class BlueCoinSwitch, ov002 0x020f11b0-0x020f15fc (9 functions, no other - * class in the TU -- tu_map.py). - * - * Two names again, as with CastleWater. The symbols mangle from - * `BlueCoinSwitch`, so the struct is spelled that way; the RTTI record calls it - * `daObjBC_Switch_c` and include/daObjBC_Switch_c.h is the generated view under - * that name. Same object, and this is the header methods are defined against. - * - * It is a Platform -- Behavior and InitResources both call - * Platform::UpdateModelPosAndRotY and Platform::UpdateClsnPosAndRot on it -- so - * mPos and mAngleY sit at Actor's offsets. Written FLAT with the inherited - * slots restated, as every other generated header here is. - * - * Field NAMES are placeholders - renaming cannot change codegen. - */ #ifndef BLUECOINSWITCH_H #define BLUECOINSWITCH_H + #include "types.h" -#include "math/Matrix.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct BlueCoinSwitch : Platform { + u8 pad_31e[0x2]; + s32 unk_320; /* 0x320 */ + s32 unk_324; /* 0x324 */ + u16 unk_328; /* 0x328 */ + u16 unk_32a; /* 0x32a */ + u8 unk_32c; /* 0x32c */ + u8 unk_32d; /* 0x32d */ + u8 unk_32e; /* 0x32e */ + + /* --- vtable --- */ + virtual ~BlueCoinSwitch(); + + s32 Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char BlueCoinSwitch_size_must_be_0x330[sizeof(BlueCoinSwitch) == 0x330 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct BlueCoinSwitch { u8 pad_000[0x8]; /* Spawn word, unpacked into two fields by InitResources: bits 0-3 become @@ -63,13 +87,8 @@ struct BlueCoinSwitch { u8 unk_32c; /* 0x32c */ u8 unk_32d; /* 0x32d */ u8 unk_32e; /* 0x32e */ -#ifdef __cplusplus - /* methods */ - s32 Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* BLUECOINSWITCH_H */ diff --git a/include/BowserFireSeaArena.h b/include/BowserFireSeaArena.h index 7dac25a5a..610aa6898 100644 --- a/include/BowserFireSeaArena.h +++ b/include/BowserFireSeaArena.h @@ -11,8 +11,7 @@ * * Two sub-objects of its own, on top of Platform's two: * - * Platform data ends 0x31e -> unk_31e - * three s16 = 0x324 -> mModel2 + * Platform 0x000 + 0x324 = 0x324 -> mModel2 * Model 0x324 + 0x050 = 0x374 -> mMovingMeshCollider2 * MovingMeshCollider 0x374 + 0x1c8 = 0x53c -> padding, then unk_56c * @@ -34,10 +33,9 @@ #include "Platform.h" struct BowserFireSeaArena : Platform { - /* Platform's data ends at 0x31e, so this class's own fields start there -- - these three, and only then mModel2 at 0x324. They were briefly declared as - Platform's; that reproduced this class either way and made StarSwitch, whose - own first s32 sits at 0x320, impossible. */ + /* THIS CLASS'S OWN, not Platform's -- Platform ends at 0x31e. They are what + push mModel2 from 0x320 to 0x324, and the first two sit in the base's + tail padding. */ s16 unk_31e; /* 0x31e */ s16 unk_320; /* 0x320 */ s16 unk_322; /* 0x322 */ diff --git a/include/BowserPuzzlePiece.h b/include/BowserPuzzlePiece.h index 8c56f4291..bf69f6f2c 100644 --- a/include/BowserPuzzlePiece.h +++ b/include/BowserPuzzlePiece.h @@ -1,11 +1,47 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class BowserPuzzlePiece: 4 matched functions, 12 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef BOWSERPUZZLEPIECE_H #define BOWSERPUZZLEPIECE_H + #include "types.h" +/* Derives from Enemy: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x110 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Enemy.h" +#include "MovingCylinderClsn.h" +#include "WithMeshClsn.h" + +struct BowserPuzzlePiece : Enemy { + MovingCylinderClsn mMovingCylinderClsn;/* 0x110 */ + WithMeshClsn mWithMeshClsn; /* 0x144 */ + u8 pad_300[0x14]; + s32 unk_314; /* 0x314 */ + s32 unk_318; /* 0x318 */ + + /* --- vtable --- */ + virtual ~BowserPuzzlePiece(); + + virtual s32 Behavior(); + virtual s32 CleanupResources(); + virtual s32 InitResources(); + virtual void OnPendingDestroy(); + virtual s32 Render(); +}; + +typedef char BowserPuzzlePiece_size_must_be_0x31c[sizeof(BowserPuzzlePiece) == 0x31c ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct BowserPuzzlePiece { u8 pad_000[0x8]; u32 unk_008; /* 0x008 */ @@ -48,14 +84,8 @@ struct BowserPuzzlePiece { u8 pad_145[0x1cf]; s32 unk_314; /* 0x314 */ s32 unk_318; /* 0x318 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - void OnPendingDestroy(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* BOWSERPUZZLEPIECE_H */ diff --git a/include/BulletBill.h b/include/BulletBill.h index 505182e47..5961ebf0d 100644 --- a/include/BulletBill.h +++ b/include/BulletBill.h @@ -1,14 +1,52 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class BulletBill: 5 matched functions, 20 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef BULLETBILL_H #define BULLETBILL_H + #include "types.h" + +/* Five boundaries close on sizes other headers assert: + * + * Enemy ends 0x110 + * MovingCylinderClsnWithPos 0x110 + 0x040 = 0x150 -> WithMeshClsn + * WithMeshClsn 0x150 + 0x1bc = 0x30c -> the first Model + * Model 0x30c + 0x050 = 0x35c -> the second + * Model 0x35c + 0x050 = 0x3ac -> the shadow + * (0x28 of shadow) 0x3ac + 0x028 = 0x3d4 -> mState + * + * The ShadowModel at 0x3ac is destroyed like the rest, and 0x3ac + 0x28 closes + * exactly on mState. + * + * unk_130 and unk_134 are gone: both fall inside the MovingCylinderClsnWithPos + * at 0x110 (+0x20 and +0x24). + */ + +#ifdef __cplusplus + +#include "Enemy.h" #include "Model.h" -#include "WithMeshClsn.h" #include "ShadowModel.h" +#include "WithMeshClsn.h" +#include "MovingCylinderClsnWithPos.h" + +struct BulletBill : Enemy { + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos; /* 0x110 */ + WithMeshClsn mWithMeshClsn; /* 0x150 */ + Model mModel1; /* 0x30c */ + Model mModel2; /* 0x35c */ + ShadowModel mShadowModel; /* 0x3ac */ + s32 mState; /* 0x3d4 */ + s32 unk_3d8; /* 0x3d8 */ + + virtual ~BulletBill(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +#else +/* The same object for a C translation unit, flat. */ struct BulletBill { u8 pad_000[0x5c]; s32 mPosX; /* 0x05c */ @@ -44,26 +82,21 @@ struct BulletBill { /* WithMeshClsn member, named by the class's own destructor calling WithMeshClsn's D1 at +0x150 -- a relocation the ROM build checks. Was a u8 marker. [_ZN10BulletBillD1Ev.c] */ - WithMeshClsn mWithMeshClsn; /* 0x150 */ + u8 mWithMeshClsn[0x1bc]; /* 0x150 */ /* Model member, named by _ZN5ModelD1Ev at +0x30c -- a relocation the ROM build checks. D1 and not D2, so it is this type and not an inlined base. Was a u8 marker. */ - Model mModel1; /* 0x30c */ + u8 mModel1[0x50]; /* 0x30c */ /* Model member, named by _ZN5ModelD1Ev at +0x35c -- a relocation the ROM build checks. D1 and not D2, so it is this type and not an inlined base. Was a u8 marker. */ - Model mModel2; /* 0x35c */ + u8 mModel2[0x50]; /* 0x35c */ /* ShadowModel member, named by the class's own destructor calling ShadowModel's D1 at +0x3ac -- a relocation the ROM build checks. Was a u8 marker. [_ZN10BulletBillD1Ev.c] */ - ShadowModel mShadowModel; /* 0x3ac */ + u8 mShadowModel[0x28]; /* 0x3ac */ s32 mState; /* 0x3d4 */ s32 unk_3d8; /* 0x3d8 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* BULLETBILL_H */ diff --git a/include/CannonHatch.h b/include/CannonHatch.h index f51eada2c..4037605ae 100644 --- a/include/CannonHatch.h +++ b/include/CannonHatch.h @@ -1,13 +1,47 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class CannonHatch: 6 matched functions, 14 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef CANNONHATCH_H #define CANNONHATCH_H + #include "types.h" -#include "Model.h" -#include "MovingMeshCollider.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct CannonHatch : Platform { + u8 pad_31e[0x2]; + s32 unk_320; /* 0x320 */ + s32 unk_324; /* 0x324 */ + s32 unk_328; /* 0x328 */ + u8 unk_32c; /* 0x32c */ + u8 unk_32d; /* 0x32d */ + u8 unk_32e; /* 0x32e */ + + /* --- vtable --- */ + virtual ~CannonHatch(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char CannonHatch_size_must_be_0x330[sizeof(CannonHatch) == 0x330 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct CannonHatch { u8 pad_000[0x8]; /* 0x008..0x05c is ActorBase's, and ActorBase.h is de-bannered -- hand-reconstructed, not generated. Was one u8 @@ -45,13 +79,8 @@ struct CannonHatch { u8 unk_32c; /* 0x32c */ u8 unk_32d; /* 0x32d */ u8 unk_32e; /* 0x32e */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* CANNONHATCH_H */ diff --git a/include/ChainChomp.h b/include/ChainChomp.h index b227c6dc4..dc63b1f78 100644 --- a/include/ChainChomp.h +++ b/include/ChainChomp.h @@ -1,12 +1,61 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class ChainChomp: 5 matched functions, 10 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef CHAINCHOMP_H #define CHAINCHOMP_H + #include "types.h" + +/* The Chain Chomp, and its chain -- seven links, which is why seven of nearly + * everything. NINE CONSECUTIVE BOUNDARIES close on sizes other headers assert, + * the longest unbroken run this branch has found: + * + * Enemy ends 0x110 + * MovingCylinderClsnWithPos 0x110 + 0x40 = 0x150 -> ModelAnim + * ModelAnim 0x150 + 0x64 = 0x1b4 -> ShadowModel + * ShadowModel 0x1b4 + 0x28 = 0x1dc -> the link models + * Model[7] 0x1dc + 7*0x50 = 0x40c -> the link shadows + * ShadowModel[7] 0x40c + 7*0x28 = 0x524 -> the first triple + * Vector3[7] 0x524 + 7*0x0c = 0x578 -> the second + * Vector3[7] 0x578 + 7*0x0c = 0x5cc + * + * Every element type was already named in the tree, so this class needed no new + * one: the two Vector3 arrays are the per-link positions. + */ + +#ifdef __cplusplus + +#include "Enemy.h" +#include "Model.h" #include "ModelAnim.h" +#include "ShadowModel.h" +#include "MovingCylinderClsnWithPos.h" + +struct ChainChomp : Enemy { + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos; /* 0x110 */ + ModelAnim mModelAnim; /* 0x150 */ + ShadowModel mShadowModel; /* 0x1b4 */ + Model mLinkModels[7]; /* 0x1dc */ + ShadowModel mLinkShadows[7]; /* 0x40c */ + Vector3 unk_524[7]; /* 0x524 */ + Vector3 unk_578[7]; /* 0x578 */ + u8 pad_5cc[0x24]; + s32 unk_5f0; /* 0x5f0 */ + u8 pad_5f4[0x11]; + u8 unk_605; /* 0x605 */ + u8 pad_606[0x6]; + s32 unk_60c; /* 0x60c */ + u8 pad_610[0xc]; + u8 unk_61c; /* 0x61c */ + u8 unk_61d; /* 0x61d */ + + virtual ~ChainChomp(); + + int Behavior(); + int InitResources(); + int Render(); +}; +#else + +/* The same object for a C translation unit, flat. */ struct ChainChomp { u8 pad_000[0x60]; s32 mPosY; /* 0x060 */ @@ -43,7 +92,7 @@ struct ChainChomp { u8 pad_111[0x3f]; /* ModelAnim member, named by _ZN9ModelAnimD1Ev at +0x150 -- a relocation the ROM build checks. D1 and not D2, so it is this type and not an inlined base. Was a u8 marker. */ - ModelAnim mModelAnim; /* 0x150 */ + u8 mModelAnim[0x64]; /* 0x150 */ u8 mShadowModel; /* 0x1b4 */ u8 pad_1b5[0x43b]; s32 unk_5f0; /* 0x5f0 */ @@ -54,12 +103,8 @@ struct ChainChomp { u8 pad_610[0xc]; u8 unk_61c; /* 0x61c */ u8 unk_61d; /* 0x61d */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* CHAINCHOMP_H */ diff --git a/include/ChainChompFence.h b/include/ChainChompFence.h index 6a668a4c0..64da15cc4 100644 --- a/include/ChainChompFence.h +++ b/include/ChainChompFence.h @@ -1,12 +1,41 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class ChainChompFence: 6 matched functions, 4 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef CHAINCHOMPFENCE_H #define CHAINCHOMPFENCE_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct ChainChompFence : Platform { + u8 unk_31e; /* 0x31e */ + + /* --- vtable --- */ + virtual ~ChainChompFence(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char ChainChompFence_size_must_be_0x320[sizeof(ChainChompFence) == 0x320 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct ChainChompFence { u8 pad_000[0x8e]; s16 unk_08e; /* 0x08e */ @@ -17,13 +46,8 @@ struct ChainChompFence { u8 mMovingMeshCollider; /* 0x124 */ u8 pad_125[0x1f9]; u8 unk_31e; /* 0x31e */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* CHAINCHOMPFENCE_H */ diff --git a/include/CheepCheep.h b/include/CheepCheep.h index 13d099e52..bdef139ad 100644 --- a/include/CheepCheep.h +++ b/include/CheepCheep.h @@ -1,13 +1,48 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class CheepCheep: 5 matched functions, 12 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef CHEEPCHEEP_H #define CHEEPCHEEP_H + #include "types.h" + +/* Derives from Enemy: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x110 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Enemy.h" +#include "ModelAnim.h" #include "MovingCylinderClsnWithPos.h" #include "WithMeshClsn.h" +struct CheepCheep : Enemy { + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos;/* 0x110 */ + WithMeshClsn mWithMeshClsn; /* 0x150 */ + ModelAnim mModelAnim; /* 0x30c */ + u8 pad_370[0x4]; + s32 unk_374; /* 0x374 */ + s32 unk_378; /* 0x378 */ + s32 unk_37c; /* 0x37c */ + + /* --- vtable --- */ + virtual ~CheepCheep(); + + int Behavior(); + int InitResources(); + int Render(); +}; + +typedef char CheepCheep_size_must_be_0x380[sizeof(CheepCheep) == 0x380 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct CheepCheep { u8 pad_000[0x5c]; s32 mPosX; /* 0x05c */ @@ -33,12 +68,8 @@ struct CheepCheep { s32 unk_374; /* 0x374 */ s32 unk_378; /* 0x378 */ s32 unk_37c; /* 0x37c */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* CHEEPCHEEP_H */ diff --git a/include/ChiefChilly.h b/include/ChiefChilly.h index 8a754c199..e50c32931 100644 --- a/include/ChiefChilly.h +++ b/include/ChiefChilly.h @@ -1,88 +1,75 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class ChiefChilly: 5 matched functions, 21 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef CHIEFCHILLY_H #define CHIEFCHILLY_H + #include "types.h" + +/* The Chief Chilly boss. Its destructor is the layout, and every member closes + * exactly on the next one: + * + * Enemy ends 0x110 + * MovingCylinderClsnWithPos 0x110 + 0x040 = 0x150 + * WithMeshClsn 0x150 + 0x1bc = 0x30c + * BlendModelAnim 0x30c + 0x070 = 0x37c -> mState + * ShadowModel 0x380 + 0x028 = 0x3a8 + * Vector3[8] 0x3e8 + 0x060 = 0x448 -> the next array + * Vector3[8] 0x448 + 0x060 = 0x4a8 + * Vector3[2] 0x4d4 + 0x018 = 0x4ec -> unk_4ec + * + * Eight boundaries, each from a size another header asserts independently. + * + * THE THREE ARRAYS ARE Vector3, and that is what named func_020072c0. The ROM + * destroys them with __destroy_arr(ptr, N, 0xc, ...), which a POD array would + * never need, and InitResources fills each element as x/y/z from the actor's + * position. See the note on Vector3 in include/types.h. + * + * unk_3d8/3dc/3e0 are NOT a Vector3 despite looking like one: the destructor + * does not touch 0x3d8, and a Vector3 member would be destroyed there. + */ + +#ifdef __cplusplus + +#include "Enemy.h" +#include "ShadowModel.h" #include "BlendModelAnim.h" +#include "WithMeshClsn.h" +#include "MovingCylinderClsnWithPos.h" -struct ChiefChilly { - u8 pad_000[0x5c]; - s32 mPosX; /* 0x05c */ - s32 mPosY; /* 0x060 */ - s32 mPosZ; /* 0x064 */ - s32 unk_068; /* 0x068 */ - s32 unk_06c; /* 0x06c */ - s32 unk_070; /* 0x070 */ - /* Camera-space position: Behavior hands `self + 0x74` to func_02012694, - which reads a Vector3 there. 0x068-0x070 is the triple it restores mPos - FROM when a ground ray misses -- see the .cpp. */ - s32 mCamSpacePosX; /* 0x074 */ - s32 mCamSpacePosY; /* 0x078 */ - s32 mCamSpacePosZ; /* 0x07c */ - s32 mScaleX; /* 0x080 */ - s32 mScaleY; /* 0x084 */ - s32 mScaleZ; /* 0x088 */ - u8 pad_08c[0x2]; - s16 mAngleY; /* 0x08e */ - u8 pad_090[0x4]; - s16 mPrevAngleY; /* 0x094 */ - u8 pad_096[0x2]; - s32 unk_098; /* 0x098 */ - s32 unk_09c; /* 0x09c */ - s32 unk_0a0; /* 0x0a0 */ - u8 pad_0a4[0x4]; - s32 unk_0a8; /* 0x0a8 */ - s32 unk_0ac; /* 0x0ac */ - u8 pad_0b0[0x50]; - u16 unk_100; /* 0x100 */ - u8 pad_102[0xe]; - u8 mMovingCylinderClsnWithPos; /* 0x110 */ - u8 pad_111[0x3f]; - u8 mWithMeshClsn; /* 0x150 */ - u8 pad_151[0x1bb]; - /* BlendModelAnim member, named by _ZN14BlendModelAnimD1Ev at +0x30c -- a relocation - the ROM build checks. D1 and not D2, so it is this type and not an inlined base. The - marker's pad stopped short of the object, so the member also takes over unk_368 - (+0x5c = speed), which the header declared separately inside it. */ - BlendModelAnim mBlendModelAnim; /* 0x30c */ - /* Current state: a record whose second word gates the tick and whose - THIRD is the pointer-to-member Behavior calls. Behavior also compares - it by ADDRESS against twelve file-scope state objects to gate five - separate things. */ - void* mState; /* 0x37c */ - u8 mShadowModel; /* 0x380 */ - u8 pad_381[0x57]; - s32 unk_3d8; /* 0x3d8 */ - s32 unk_3dc; /* 0x3dc */ - s32 unk_3e0; /* 0x3e0 */ - u8 pad_3e4[0xd8]; - s32 unk_4bc; /* 0x4bc */ +struct ChiefChilly : Enemy { + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos; /* 0x110 */ + WithMeshClsn mWithMeshClsn; /* 0x150 */ + BlendModelAnim mBlendModelAnim; /* 0x30c */ + void *mState; /* 0x37c */ + ShadowModel mShadowModel; /* 0x380 */ + u8 pad_3a8[0x30]; + s32 unk_3d8; /* 0x3d8 */ + s32 unk_3dc; /* 0x3dc */ + s32 unk_3e0; /* 0x3e0 */ + u8 pad_3e4[0x4]; + Vector3 unk_3e8[8]; /* 0x3e8 */ + Vector3 unk_448[8]; /* 0x448 */ + u8 pad_4a8[0x14]; + s32 unk_4bc; /* 0x4bc */ u8 pad_4c0[0x5]; - u8 unk_4c5; /* 0x4c5 */ + u8 unk_4c5; /* 0x4c5 */ u8 pad_4c6[0x3]; - /* Set when a downward ray finds nothing AND the fall is fast enough; - cleared whenever the ray hits. */ - u8 unk_4c9; /* 0x4c9 */ + u8 unk_4c9; /* 0x4c9 */ u8 pad_4ca[0x1]; - u8 unk_4cb; /* 0x4cb */ - u8 pad_4cc[0x20]; - /* Last position before a failed ground ray rewound mPos. Written every - time the ray misses, so it is the position the rewind came FROM. - These three sit PAST where this header used to end (0x4cc); Behavior - writes them, so the struct is at least 0x4f8. */ - s32 unk_4ec; /* 0x4ec */ - s32 unk_4f0; /* 0x4f0 */ - s32 unk_4f4; /* 0x4f4 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - void OnPendingDestroy(); - int Render(); -#endif + u8 unk_4cb; /* 0x4cb */ + u8 pad_4cc[0x8]; + Vector3 unk_4d4[2]; /* 0x4d4 */ + s32 unk_4ec; /* 0x4ec */ + s32 unk_4f0; /* 0x4f0 */ + s32 unk_4f4; /* 0x4f4 */ + + virtual ~ChiefChilly(); + + virtual s32 InitResources(); + virtual s32 CleanupResources(); + virtual s32 Behavior(); + virtual s32 Render(); + virtual void OnPendingDestroy(); }; -#endif +#endif /* __cplusplus */ + +#endif /* CHIEFCHILLY_H */ diff --git a/include/CylinderClsn.h b/include/CylinderClsn.h index 0de68894c..0b9eca0ac 100644 --- a/include/CylinderClsn.h +++ b/include/CylinderClsn.h @@ -50,6 +50,8 @@ #ifdef __cplusplus +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct CylinderClsn { /* 0x00 is the vptr, placed implicitly by the first virtual declaration. */ Fix12i radius; /* 0x04 - Init arg 1 */ @@ -72,6 +74,23 @@ struct CylinderClsn { void Clear(); void Update(); static void Process(); + + /* WHAT LETS A REAL `~Class()` REPRODUCE THE ROM'S DELETING DESTRUCTOR. + The compiler generates D0 as "run the destructor body, then call operator + delete on the class". Without this it emits the global `_ZdlPv`, which + exists nowhere in this image, and the D0 comes out one relocated word + different from the ROM -- a difference build_pin.verify CANNOT SEE, + because it wildcards relocated words. Only the link catches it. + + This family deallocates through Memory::operator_delete2, not the actor + heap: every D0 below ends with a call to 0x0203cbcc. Actor's copy of this + member calls Memory::Deallocate instead, which is why each needs its own. + + Inline, and in the IMMEDIATE base -- mwcc inlines it only when it finds it + in the class or one level up, as include/Actor.h records. No layout + effect: a non-virtual inline member adds no field and no vtable slot. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; typedef char CylinderClsn_size_must_be_0x30[sizeof(CylinderClsn) == 0x30 ? 1 : -1]; diff --git a/include/DonutBlock.h b/include/DonutBlock.h index 64d92eb69..26a1f47a1 100644 --- a/include/DonutBlock.h +++ b/include/DonutBlock.h @@ -2,27 +2,27 @@ #define DONUTBLOCK_H #include "types.h" -#include "Platform.h" -/* Derives from Platform: the destructor stores this class's vtable, then - * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and - * the Model at 0xd4 before chaining to Actor. All three are Platform's. - * Everything this header used to restate below 0x31e was Actor's and - * Platform's. +/* A donut lift: stands still until ridden, then shakes, falls and respawns. * - * THE FIELDS AT 0x31e/0x31f ARE IN PLATFORM'S TAIL PADDING. Platform's last - * field ends at 0x31e and its size rounds to 0x320; the Itanium ABI lets a - * derived class use a non-POD base's tail padding, and the ROM does. The bytes - * settle it -- code here reads this+0x31e and reproduces. + * Everything this header used to declare below 0x31e was Actor's and + * Platform's, restated. It derives from Platform now, which the destructor + * evidences the usual way -- it stores DonutBlock's vtable, then Platform's, + * then destroys the MovingMeshCollider at 0x124 and the Model at 0xd4 and + * chains to Actor. Those three are Platform's own. * - * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it - * is not independent evidence about the ROM. + * unk_31e sits at 0x31e, in Platform's TAIL PADDING: Platform's last field + * ends at 0x31e and its size rounds to 0x320, and the Itanium ABI lets a + * derived class place members in a non-POD base's tail padding. Behavior reads + * this+0x31e and reproduces the ROM, which is what confirms the placement. */ #ifdef __cplusplus +#include "Platform.h" + struct DonutBlock : Platform { - s16 unk_31e; /* 0x31e - in Platform's tail padding */ + s16 unk_31e; /* 0x31e - per-frame yaw step; see InitResources */ /* --- vtable --- */ virtual ~DonutBlock(); diff --git a/include/Enemy.h b/include/Enemy.h index a64e32f9b..62866a940 100644 --- a/include/Enemy.h +++ b/include/Enemy.h @@ -5,6 +5,7 @@ #ifndef ENEMY_H #define ENEMY_H #include "types.h" +#include "Actor.h" /* fwd */ struct CylinderClsn; @@ -24,87 +25,44 @@ struct ww_; extern "C" void _ZN6Memory10DeallocateEPvP4Heap(void *, void *); extern "C" void *data_020a0eac; -struct Enemy { - /* 0x00 is the vptr, placed implicitly by the virtual destructor declared - below. The 0x5c of padding that used to start at 0x00 therefore starts - at 0x04 and is four bytes shorter -- Enemy's 0x110 span always counted - the vptr, it just was not declared. Adding a virtual WITHOUT taking the - four bytes back pushes every field, and every member of every derived - class, four bytes late. +struct Enemy : Actor { + /* DERIVES FROM Actor, at last -- this header used to restate Actor's whole + layout, and its own note said `Enemy : Actor` was "the real fix and is + its own slice". Everything below 0x0d0 is Actor's and is inherited now; + the thirteen fields that were duplicated here resolve through Actor.h, + two of which (0x0a4, 0x0ac) were padding there until this class proved + they are real. - Enemy really inherits this vptr from ActorBase via Actor -- the fields - below 0x0d0 duplicate Actor's, as the notes in this file already say. - Declaring the destructor here is true but incomplete; `Enemy : Actor` - is the real fix and is its own slice. */ - u8 pad_004[0x4]; - s32 mParam; /* 0x008 */ - u8 pad_00c[0x50]; - s32 mPosX; /* 0x05c */ - s32 mPosY; /* 0x060 */ - s32 mPosZ; /* 0x064 */ - u8 pad_068[0x24]; - /* 0x08c-0x090 are Actor.h:91-93 mAngleX/Y/Z, the rotation triple. - Enemy::UpdateKillByInvincibleChar adds the spin rates at 0x0ec-0x0f0 to - these three in ascending order and hands the same three, in the same - order, to Matrix4x3_ApplyInPlaceToRotationZXYExt -- consistent with - Actor.h's assignment, which is the primary evidence. */ - s16 mAngleX; /* 0x08c */ - s16 mAngleY; /* 0x08e */ - s16 mAngleZ; /* 0x090 */ - u8 pad_092[0x2]; - /* 0x094 is Actor.h:95 mPrevAngleY. The ROM loads it with a signed halfword - load, which is the one thing no source pass can settle -- and 27 derived - headers already declare it s16. Was a bare u8 marker. */ - s16 mPrevAngleY; /* 0x094 */ - u8 pad_096[0x6]; - s32 unk_09c; /* 0x09c */ - s32 unk_0a0; /* 0x0a0 */ - s32 unk_0a4; /* 0x0a4 */ - /* 0x0a8 is Actor.h:99 mVertSpeed; 10 derived headers agree, both evidence - passes see 4-byte accesses. */ - s32 mVertSpeed; /* 0x0a8 */ - /* 0x0ac: no Actor field, but 6 derived headers agree and both passes see - 4-byte accesses. The marker's span ran to 0x0d4; only its first word is - evidenced, so the rest stays padding. */ - s32 unk_0ac; /* 0x0ac */ - u8 pad_0b0[0x24]; - /* Two surface normals, written a Vector3 at a time by - SurfaceInfo::CopyNormalTo in Enemy::UpdateWMClsn -- the floor result's - normal into 0x0d4, the wall result's into 0x0e0. The wall triple was - declared u8 + pad + u8, which made any natural access an ldrb; - Enemy::AngleAwayFromWallOrCliff reads X and Z of it as four-byte values - and hands them to Actor::ReflectAngle, which is what a wall normal is - for. Same shape and same names as Player.h's mFloorNormalX/Y/Z. */ + Actor is 0xd0, so Enemy's own fields start there and its 0x110 closes + exactly on the subclasses that follow it. */ + /* FIVE FIELDS BELOW WERE PADDING HERE and are named on the same kind of + evidence that took Actor's 0x0a4/0x0ac: the subclasses declare them and + read them, and `X : Enemy` cannot compile unless they exist. The counts + are how many of Enemy's 51 subclasses declare each -- 0x100 is in + twenty-eight of them, which is not a coincidence. The names stay unk_ + where the meaning is unevidenced. */ + s32 mEatingPlayer; /* 0x0d0 -- 4 subclasses */ s32 mFloorNormalX; /* 0x0d4 */ s32 mFloorNormalY; /* 0x0d8 */ s32 mFloorNormalZ; /* 0x0dc */ - s32 mWallNormalX; /* 0x0e0 */ - s32 mWallNormalY; /* 0x0e4 */ - s32 mWallNormalZ; /* 0x0e8 */ - /* Per-frame spin applied while the enemy is dying. KillByInvincibleChar - (ov002 0x020ada40) copies the three s16 of its `const Vector3_16 &` - argument straight into these slots; UpdateKillByInvincibleChar then adds - them to mAngleX/Y/Z once a frame. Named from that behaviour -- the ROM - evidences the widths and the copy, not the intent. */ - s16 mSpinRateX; /* 0x0ec */ - s16 mSpinRateY; /* 0x0ee */ - s16 mSpinRateZ; /* 0x0f0 */ - u8 pad_0f2[0x10]; - /* Death timer, counted down a frame at a time. Was s16: every read in the - tree is unsigned -- two ldrh in UpdateKillByInvincibleChar, and - UpdateDeath's DecIfAbove0_Short is `unsigned short*` in both its source - and its ROM bytes (ldrh at 0x0203adbc). No reference reads it signed, - so the declared sign was wrong rather than locally over-ridden. */ - u16 mDeathTimer; /* 0x102 */ - u8 pad_104[0x2]; - u8 unk_106; /* 0x106 */ - u8 unk_107; /* 0x107 */ - u8 pad_108[0x4]; - /* 0x10c: 4 derived headers agree, history sees 4 four-byte accesses and the - ROM two. This is the last field, so widening it grows sizeof(Enemy) by 3 -- - the only site here that is not offset-neutral. */ - s32 mDeathState; /* 0x10c */ - /* --- vtable, in ROM order. Do not reorder. --- */ + s32 mWallNormalX; /* 0x0e0 */ + s32 mWallNormalY; /* 0x0e4 */ + s32 mWallNormalZ; /* 0x0e8 */ + s16 mSpinRateX; /* 0x0ec */ + s16 mSpinRateY; /* 0x0ee */ + s16 mSpinRateZ; /* 0x0f0 */ + u8 pad_0f2[0xe]; + s16 unk_100; /* 0x100 -- 28 subclasses */ + u16 mDeathTimer; /* 0x102 */ + u16 unk_104; /* 0x104 -- 5 subclasses */ + u8 unk_106; /* 0x106 */ + u8 unk_107; /* 0x107 */ + u8 unk_108; /* 0x108 -- 10 subclasses */ + u8 pad_109[0x1]; + u8 unk_10a; /* 0x10a -- 5 subclasses */ + u8 pad_10b[0x1]; + s32 mDeathState; /* 0x10c */ + virtual ~Enemy(); /* slots 0 (D1), 1 (D0) */ /* Enemy's own copy of Actor's inline operator delete, and it has to be its diff --git a/include/FireSeaElevator.h b/include/FireSeaElevator.h index bb47ab1a6..e0df67b05 100644 --- a/include/FireSeaElevator.h +++ b/include/FireSeaElevator.h @@ -1,13 +1,44 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class FireSeaElevator: 6 matched functions, 6 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef FIRESEAELEVATOR_H #define FIRESEAELEVATOR_H + #include "types.h" -#include "Model.h" + +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" #include "MovingCylinderClsn.h" +struct FireSeaElevator : Platform { + u8 pad_31e[0x2]; + MovingCylinderClsn mMovingCylinderClsn;/* 0x320 */ + u16 unk_354; /* 0x354 */ + + /* --- vtable --- */ + virtual ~FireSeaElevator(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char FireSeaElevator_size_must_be_0x358[sizeof(FireSeaElevator) == 0x358 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct FireSeaElevator { u8 pad_000[0x8]; s32 unk_008; /* 0x008 */ @@ -24,13 +55,8 @@ struct FireSeaElevator { checks. Was a u8 marker. [_ZN15FireSeaElevatorD1Ev.c] */ MovingCylinderClsn mMovingCylinderClsn; /* 0x320 */ u16 unk_354; /* 0x354 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* FIRESEAELEVATOR_H */ diff --git a/include/FloatingFloorLllBig.h b/include/FloatingFloorLllBig.h index fd298fc4f..50dba9769 100644 --- a/include/FloatingFloorLllBig.h +++ b/include/FloatingFloorLllBig.h @@ -2,25 +2,23 @@ #define FLOATINGFLOORLLLBIG_H #include "types.h" -#include "Platform.h" /* Derives from Platform: the destructor stores this class's vtable, then - * Platform's -- inlined -- and then destroys the MovingMeshCollider at 0x124 - * and the Model at 0xd4 before chaining to Actor. Those three are Platform's - * and are declared there; everything this header used to restate below 0x31e - * was Actor's and Platform's. - * - * Any field at 0x31e or 0x31f sits in Platform's tail padding, which the - * Itanium ABI lets a derived class use because Platform is non-POD: its last - * field ends at 0x31e and its size rounds to 0x320. + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. * - * SIZE IS THE OBSERVED FIELD SPAN, rounded up -- not independent evidence. It - * is a regression guard on this declaration, not a claim about the ROM. + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. */ #ifdef __cplusplus +#include "Platform.h" + struct FloatingFloorLllBig : Platform { + u8 pad_31e[0x2]; s32 unk_320; /* 0x320 */ s16 unk_324; /* 0x324 */ @@ -34,6 +32,27 @@ struct FloatingFloorLllBig : Platform { typedef char FloatingFloorLllBig_size_must_be_0x328[sizeof(FloatingFloorLllBig) == 0x328 ? 1 : -1]; +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ +struct FloatingFloorLllBig { + u8 pad_000[0x60]; + s32 mPosY; /* 0x060 */ + u8 pad_064[0x28]; + s16 mAngleX; /* 0x08c */ + s16 mAngleY; /* 0x08e */ + u8 pad_090[0x44]; + /* Model member, named by _ZN5ModelD1Ev at +0xd4 -- a relocation the ROM build checks. + D1 and not D2, so it is this type and not an inlined base. Was a u8 marker. */ + Model mModel; /* 0x0d4 */ + u8 mMeshCollider; /* 0x124 */ + u8 pad_125[0x1fb]; + s32 unk_320; /* 0x320 */ + s16 unk_324; /* 0x324 */ +}; + #endif /* __cplusplus */ #endif /* FLOATINGFLOORLLLBIG_H */ diff --git a/include/FortressTower.h b/include/FortressTower.h index 56b6d21c4..260e1c33e 100644 --- a/include/FortressTower.h +++ b/include/FortressTower.h @@ -1,12 +1,41 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class FortressTower: 6 matched functions, 3 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef FORTRESSTOWER_H #define FORTRESSTOWER_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct FortressTower : Platform { + /* no fields of its own */ + + /* --- vtable --- */ + virtual ~FortressTower(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char FortressTower_size_must_be_0x320[sizeof(FortressTower) == 0x320 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct FortressTower { u8 pad_000[0xc]; u16 unk_00c; /* 0x00c */ @@ -15,13 +44,8 @@ struct FortressTower { D1 and not D2, so it is this type and not an inlined base. Was a u8 marker. */ Model mModel; /* 0x0d4 */ u8 mMovingMeshCollider; /* 0x124 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* FORTRESSTOWER_H */ diff --git a/include/FortressWall.h b/include/FortressWall.h index 8dad08bf5..95594a14e 100644 --- a/include/FortressWall.h +++ b/include/FortressWall.h @@ -2,18 +2,12 @@ #define FORTRESSWALL_H #include "types.h" -#include "Platform.h" /* Derives from Platform: the destructor stores this class's vtable, then * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and - * the Model at 0xd4 before chaining to Actor. All three are Platform's. + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. * Everything this header used to restate below 0x31e was Actor's and - * Platform's. - * - * THE FIELDS AT 0x31e/0x31f ARE IN PLATFORM'S TAIL PADDING. Platform's last - * field ends at 0x31e and its size rounds to 0x320; the Itanium ABI lets a - * derived class use a non-POD base's tail padding, and the ROM does. The bytes - * settle it -- code here reads this+0x31e and reproduces. + * Platform's, and is inherited now. * * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it * is not independent evidence about the ROM. @@ -21,12 +15,14 @@ #ifdef __cplusplus +#include "Platform.h" + struct FortressWall : Platform { - u8 unk_31e; /* 0x31e - in Platform's tail padding */ - u8 unk_31f; /* 0x31f */ + u8 unk_31e; /* 0x31e */ + u8 unk_31f; /* 0x31f */ u8 pad_320[0x1]; - u8 unk_321; /* 0x321 */ - u8 unk_322; /* 0x322 */ + u8 unk_321; /* 0x321 */ + u8 unk_322; /* 0x322 */ /* --- vtable --- */ virtual ~FortressWall(); @@ -39,6 +35,49 @@ struct FortressWall : Platform { typedef char FortressWall_size_must_be_0x324[sizeof(FortressWall) == 0x324 ? 1 : -1]; +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ +struct FortressWall { + u8 pad_000[0x8]; + s32 mParam; /* 0x008 */ + u16 mActorID; /* 0x00c */ + u8 pad_00e[0x4e]; + /* Actor::mPosX -- Actor.h declares s32 here, and it is de-bannered (hand-reconstructed). */ + s32 unk_05c; /* 0x05c */ + /* Actor::mPosY -- Actor.h declares s32 here, and it is de-bannered (hand-reconstructed). */ + s32 unk_060; /* 0x060 */ + /* 0x064..0x08e is Actor's, and Actor.h is de-bannered -- hand-reconstructed, not generated. Was one u8 + marker over the whole range. */ + s32 unk_064; /* 0x064 */ + s32 unk_068; /* 0x068 */ + s32 unk_06c; /* 0x06c */ + s32 unk_070; /* 0x070 */ + s32 mCamSpacePosX; /* 0x074 */ + s32 mCamSpacePosY; /* 0x078 */ + s32 mCamSpacePosZ; /* 0x07c */ + s32 mScaleX; /* 0x080 */ + s32 mScaleY; /* 0x084 */ + s32 mScaleZ; /* 0x088 */ + s16 mAngleX; /* 0x08c */ + s16 mAngleY; /* 0x08e */ + u8 pad_090[0x3c]; + u8 mAreaId; /* 0x0cc */ + u8 pad_0cd[0x7]; + /* Model member, named by _ZN5ModelD1Ev at +0xd4 -- a relocation the ROM build checks. + D1 and not D2, so it is this type and not an inlined base. Was a u8 marker. */ + Model mModel; /* 0x0d4 */ + u8 mMeshCollider; /* 0x124 */ + u8 pad_125[0x1f9]; + u8 unk_31e; /* 0x31e */ + u8 unk_31f; /* 0x31f */ + u8 pad_320[0x1]; + u8 unk_321; /* 0x321 */ + u8 unk_322; /* 0x322 */ +}; + #endif /* __cplusplus */ #endif /* FORTRESSWALL_H */ diff --git a/include/Goomboss.h b/include/Goomboss.h index 5f7a7d95b..79a890546 100644 --- a/include/Goomboss.h +++ b/include/Goomboss.h @@ -1,11 +1,83 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class Goomboss: 6 matched functions, 37 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef GOOMBOSS_H #define GOOMBOSS_H + #include "types.h" +/* The Goomboss. Its destructor is the layout, and eight boundaries close on + * sizes other headers assert: + * + * Enemy ends 0x110 + * MovingCylinderClsnWithPos[4] 0x110 + 4*0x40 = 0x210 -> ModelAnim + * ModelAnim 0x210 + 0x64 = 0x274 -> the shadows + * ShadowModel[3] 0x274 + 3*0x28 = 0x2ec + * Vector3[3] 0x3ac + 3*0x0c = 0x3d0 -> MaterialChanger + * MaterialChanger 0x3d0 + 0x14 = 0x3e4 -> TextureSequence + * TextureSequence 0x3e4 + 0x14 = 0x3f8 -> TextureTransformer + * TextureTransformer 0x3f8 + 0x14 = 0x40c -> WithMeshClsn + * WithMeshClsn 0x40c + 0x1bc = 0x5c8 + * + * SIX OF THE GENERATED FIELDS WERE THE Vector3 ARRAY'S OWN COMPONENTS. + * unk_3b8/3bc/3c0 are element 1's x/y/z and unk_3c4/3c8/3cc are element 2's -- + * the header had split a Vector3[3] into nine scalars and named six of them. + * unk_3d8 and unk_3f0 are likewise inside the MaterialChanger and the + * TextureSequence. + */ + +#ifdef __cplusplus + +#include "Enemy.h" +#include "ModelAnim.h" +#include "ShadowModel.h" +#include "MaterialChanger.h" +#include "TextureSequence.h" +#include "TextureTransformer.h" +#include "WithMeshClsn.h" +#include "MovingCylinderClsnWithPos.h" + +struct Goomboss : Enemy { + MovingCylinderClsnWithPos mCylinderClsns[4]; /* 0x110 */ + ModelAnim mModelAnim; /* 0x210 */ + ShadowModel mShadowModels[3]; /* 0x274 */ + u8 pad_2ec[0xc0]; + Vector3 unk_3ac[3]; /* 0x3ac */ + MaterialChanger mMaterialChanger; /* 0x3d0 */ + TextureSequence mTextureSequence; /* 0x3e4 */ + TextureTransformer mTextureTransformer; /* 0x3f8 */ + WithMeshClsn mWithMeshClsn; /* 0x40c */ + u8 pad_5c8[0x4]; + s32 unk_5cc; /* 0x5cc */ + s32 unk_5d0; /* 0x5d0 */ + s32 unk_5d4; /* 0x5d4 */ + s32 unk_5d8; /* 0x5d8 */ + s32 unk_5dc; /* 0x5dc */ + u8 pad_5e0[0x4]; + s32 unk_5e4; /* 0x5e4 */ + s32 unk_5e8; /* 0x5e8 */ + u8 pad_5ec[0x4]; + s32 unk_5f0; /* 0x5f0 */ + u16 unk_5f4; /* 0x5f4 */ + s16 unk_5f6; /* 0x5f6 */ + s16 unk_5f8; /* 0x5f8 */ + u8 pad_5fa[0x4]; + u8 unk_5fe; /* 0x5fe */ + u8 unk_5ff; /* 0x5ff */ + u8 pad_600[0x4]; + u8 mSizeIndex; /* 0x604 */ + u8 pad_605[0x5]; + u8 unk_60a; /* 0x60a */ + + virtual ~Goomboss(); + + virtual s32 Behavior(); + virtual s32 CleanupResources(); + virtual s32 Render(); +}; + +typedef char Goomboss_size_must_be_0x60c[sizeof(Goomboss) == 0x60c ? 1 : -1]; + +#else + +/* The same object for a C translation unit, flat. */ struct Goomboss { u8 pad_000[0x8]; s32 mParam; /* 0x008 */ @@ -69,12 +141,8 @@ struct Goomboss { u8 mSizeIndex; /* 0x604 */ u8 pad_605[0x5]; u8 unk_60a; /* 0x60a */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* GOOMBOSS_H */ diff --git a/include/HUD.h b/include/HUD.h index cc5ff018c..8d1fa9dc4 100644 --- a/include/HUD.h +++ b/include/HUD.h @@ -1,13 +1,57 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class HUD: 11 matched functions, 4 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef HUD_H #define HUD_H + #include "types.h" +#include "ActorDerived.h" + +/* Derives from ActorDerived: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x50 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +struct HUD : ActorDerived { + u8 pad_050[0x10]; + u16 mVsTimer; /* 0x060 */ + u8 pad_062[0x4]; + u16 mVsTimerY; /* 0x066 */ + s16 mHealthMeterY; /* 0x068 */ + u16 mHealthMeterHoldTimer; /* 0x06a */ + u16 mHealthTickTimer; /* 0x06c */ + u8 pad_06e[0x2]; + s16 mStarCountX; /* 0x070 */ + u8 pad_072[0x1]; + u8 mHealthMeterState; /* 0x073 */ + s8 mDigits[3]; /* 0x074 */ -/* fwd */ -struct value; + /* --- vtable --- */ + virtual ~HUD(); + + int Render(); + s32 CleanupResources(); + void CalculateDigits(unsigned short value); + void OnPendingDestroy(); + void RenderHealthMeter(); + void RenderRedCoins(); + void RenderSilverStars(); + void RenderStarCount(); + void RenderTimeTimer(); + void RenderVsTimer(); + void UpdateHealthMeter(); +}; + +typedef char HUD_size_must_be_0x78[sizeof(HUD) == 0x78 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct HUD { u8 pad_000[0x60]; /* Seconds left on the VS-mode clock. RenderVsTimer splits it /10 and %10 @@ -38,20 +82,8 @@ struct HUD { RenderCoinCount reaches the same bytes through a `char pad[0x74]` shadow; that file is a separate slice. */ s8 mDigits[3]; /* 0x074 */ -#ifdef __cplusplus - /* methods */ - int Render(); - s32 CleanupResources(); - void CalculateDigits(unsigned short value); - void OnPendingDestroy(); - void RenderHealthMeter(); - void RenderRedCoins(); - void RenderSilverStars(); - void RenderStarCount(); - void RenderTimeTimer(); - void RenderVsTimer(); - void UpdateHealthMeter(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* HUD_H */ diff --git a/include/Heap.h b/include/Heap.h index 249fad0b8..2eddbfed0 100644 --- a/include/Heap.h +++ b/include/Heap.h @@ -138,6 +138,8 @@ struct Heap { u32 flags; /* 0x10 */ }; #else +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct Heap { void* heapStart; /* 0x04 -- first byte of the arena this heap hands out; for a root heap it is the heap @@ -250,6 +252,20 @@ struct Heap { 0x30 bytes for the solid one, 0x4c for the expanding one. */ static struct SolidHeapAllocator* CreateSolidHeapAllocator(void* address, u32 size, u32 flags); static struct ExpandingHeapAllocator* CreateExpandingHeapAllocator(void* address, u32 size, u32 flags); + + /* WHAT LETS A REAL `~Class()` REPRODUCE THE ROM'S DELETING DESTRUCTOR. + Without it the compiler emits the global `_ZdlPv`, which exists nowhere + in this image, and D0 comes out one relocated word different from the + ROM -- a difference build_pin.verify CANNOT SEE, because it wildcards + relocated words. Only the link catches it. + + This family deallocates through Memory::operator_delete2; Actor's copy of + this member calls Memory::Deallocate instead, which is why each family + needs its own. Inline and in the IMMEDIATE base: mwcc inlines it only + when it finds it in the class or one level up (see include/Actor.h). + No layout effect. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; #endif diff --git a/include/HugeCover.h b/include/HugeCover.h index 25b9e9c0d..74a95e19b 100644 --- a/include/HugeCover.h +++ b/include/HugeCover.h @@ -1,12 +1,43 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class HugeCover: 6 matched functions, 5 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef HUGECOVER_H #define HUGECOVER_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "TextureTransformer.h" + +struct HugeCover : Platform { + u8 pad_31e[0x2]; + TextureTransformer mTextureTransformer;/* 0x320 */ + + /* --- vtable --- */ + virtual ~HugeCover(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char HugeCover_size_must_be_0x334[sizeof(HugeCover) == 0x334 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct HugeCover { u8 pad_000[0xd4]; /* Model member, named by _ZN5ModelD1Ev at +0xd4 -- a relocation the ROM build checks. @@ -19,13 +50,8 @@ struct HugeCover { u8 mTextureTransformer; /* 0x320 */ u8 pad_321[0xb]; s32 unk_32c; /* 0x32c */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* HUGECOVER_H */ diff --git a/include/IceBlock.h b/include/IceBlock.h index bde680c8a..fc61cb87f 100644 --- a/include/IceBlock.h +++ b/include/IceBlock.h @@ -1,12 +1,49 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class IceBlock: 6 matched functions, 14 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef ICEBLOCK_H #define ICEBLOCK_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "MovingCylinderClsn.h" + +struct IceBlock : Platform { + u8 pad_31e[0x2]; + MovingCylinderClsn mMovingCylinderClsn;/* 0x320 */ + u8 unk_354; /* 0x354 */ + u8 pad_355[0x3]; + s32 mScale; /* 0x358 */ + u32 unk_35c; /* 0x35c */ + u32 unk_360; /* 0x360 */ + u8 unk_364; /* 0x364 */ + + /* --- vtable --- */ + virtual ~IceBlock(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char IceBlock_size_must_be_0x368[sizeof(IceBlock) == 0x368 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct IceBlock { u8 pad_000[0x5c]; s32 mPosX; /* 0x05c */ @@ -32,13 +69,8 @@ struct IceBlock { u32 unk_35c; /* 0x35c */ u32 unk_360; /* 0x360 */ u8 unk_364; /* 0x364 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* ICEBLOCK_H */ diff --git a/include/IceSheet.h b/include/IceSheet.h index 86defc7d9..a2a1de588 100644 --- a/include/IceSheet.h +++ b/include/IceSheet.h @@ -1,12 +1,41 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class IceSheet: 6 matched functions, 3 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef ICESHEET_H #define ICESHEET_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct IceSheet : Platform { + /* no fields of its own */ + + /* --- vtable --- */ + virtual ~IceSheet(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char IceSheet_size_must_be_0x320[sizeof(IceSheet) == 0x320 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct IceSheet { u8 pad_000[0x8e]; s16 unk_08e; /* 0x08e */ @@ -15,13 +44,8 @@ struct IceSheet { D1 and not D2, so it is this type and not an inlined base. Was a u8 marker. */ Model mModel; /* 0x0d4 */ u8 mMovingMeshCollider; /* 0x124 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* ICESHEET_H */ diff --git a/include/KingBobOmb.h b/include/KingBobOmb.h index e26400118..39e92136d 100644 --- a/include/KingBobOmb.h +++ b/include/KingBobOmb.h @@ -1,15 +1,68 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class KingBobOmb: 5 matched functions, 27 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef KINGBOBOMB_H #define KINGBOBOMB_H + #include "types.h" + +/* Derives from Enemy: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x110 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Enemy.h" #include "BlendModelAnim.h" -#include "WithMeshClsn.h" -#include "MovingCylinderClsnWithPos.h" #include "CommonModel.h" +#include "MovingCylinderClsnWithPos.h" +#include "ShadowModel.h" +#include "WithMeshClsn.h" + +struct KingBobOmb : Enemy { + WithMeshClsn mWithMeshClsn; /* 0x110 */ + BlendModelAnim mBlendModelAnim; /* 0x2cc */ + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos;/* 0x33c */ + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos_37c;/* 0x37c */ + CommonModel mCommonModel; /* 0x3bc */ + ShadowModel mShadowModel; /* 0x3f8 */ + u8 pad_420[0x74]; + s32 unk_494; /* 0x494 */ + u8 unk_498; /* 0x498 */ + u8 pad_499[0x7]; + s32 unk_4a0; /* 0x4a0 */ + u8 pad_4a4[0x30]; + s32 unk_4d4; /* 0x4d4 */ + s32 unk_4d8; /* 0x4d8 */ + s32 unk_4dc; /* 0x4dc */ + s32 unk_4e0; /* 0x4e0 */ + s32 unk_4e4; /* 0x4e4 */ + s32 unk_4e8; /* 0x4e8 */ + u8 pad_4ec[0x10]; + s32 unk_4fc; /* 0x4fc */ + s32 unk_500; /* 0x500 */ + u8 pad_504[0x3]; + u8 unk_507; /* 0x507 */ + u8 pad_508[0x1]; + u8 unk_509; /* 0x509 */ + + /* --- vtable --- */ + virtual ~KingBobOmb(); + + int Behavior(); + int InitResources(); + int Render(); +}; +typedef char KingBobOmb_size_must_be_0x50c[sizeof(KingBobOmb) == 0x50c ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct KingBobOmb { u8 pad_000[0x8]; s32 mParam; /* 0x008 */ @@ -75,12 +128,8 @@ struct KingBobOmb { u8 unk_507; /* 0x507 */ u8 pad_508[0x1]; u8 unk_509; /* 0x509 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* KINGBOBOMB_H */ diff --git a/include/KnockDownPlank.h b/include/KnockDownPlank.h index c1d8534e5..a31adf4e2 100644 --- a/include/KnockDownPlank.h +++ b/include/KnockDownPlank.h @@ -1,12 +1,45 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class KnockDownPlank: 6 matched functions, 11 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef KNOCKDOWNPLANK_H #define KNOCKDOWNPLANK_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct KnockDownPlank : Platform { + u8 pad_31e[0x2]; + s32 unk_320; /* 0x320 */ + s32 unk_324; /* 0x324 */ + s32 unk_328; /* 0x328 */ + s32 mVariant; /* 0x32c */ + + /* --- vtable --- */ + virtual ~KnockDownPlank(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char KnockDownPlank_size_must_be_0x330[sizeof(KnockDownPlank) == 0x330 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct KnockDownPlank { u8 pad_000[0xc]; /* 0x00c..0x05c is ActorBase's, and ActorBase.h is de-bannered -- hand-reconstructed, not generated. Was one u8 @@ -50,13 +83,8 @@ struct KnockDownPlank { s32 unk_324; /* 0x324 */ s32 unk_328; /* 0x328 */ s32 mVariant; /* 0x32c */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* KNOCKDOWNPLANK_H */ diff --git a/include/KoopaShell.h b/include/KoopaShell.h index bdca63d04..a9e5ede77 100644 --- a/include/KoopaShell.h +++ b/include/KoopaShell.h @@ -1,22 +1,70 @@ -/* Hand-written from matched-function evidence, not gen_header.py output: - * class KoopaShell, 5 matched functions in one clean TU (ov102 - * 0x0214c748-0x0214d70c, 24 functions, no other class in it -- tu_map.py). - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * - * KoopaShell derives from Enemy -- Behavior calls Enemy::UpdateYoshiEat and - * Enemy::UpdateWMClsn on itself, and Enemy spans exactly 0x110, which is where - * this class's own sub-objects start. It is written FLAT anyway, with the - * inherited slots restated as padding and named fields, because that is what - * every other generated header in this tree does and because Enemy.h asserts - * no size for a derived struct to build on. Restating a base is a known cost; - * re-basing the whole family is its own slice. - * - * Field NAMES are placeholders - renaming cannot change codegen. - */ #ifndef KOOPASHELL_H #define KOOPASHELL_H + #include "types.h" +/* Six boundaries close on sizes other headers assert: + * + * Enemy ends 0x110 + * MovingCylinderClsn 0x110 + 0x034 = 0x144 -> WithMeshClsn + * WithMeshClsn 0x144 + 0x1bc = 0x300 -> Model + * Model 0x300 + 0x050 = 0x350 -> ShadowModel + * ShadowModel 0x350 + 0x028 = 0x378 -> the second cylinder + * MovingCylinderClsn 0x378 + 0x034 = 0x3ac -> mState + * + * Two cylinder collisions, one at each end of the shell. + */ + +#ifdef __cplusplus + +#include "Enemy.h" +#include "Model.h" +#include "ShadowModel.h" +#include "WithMeshClsn.h" +#include "MovingCylinderClsn.h" + +struct KoopaShell : Enemy { + MovingCylinderClsn mCylinderClsn; /* 0x110 */ + WithMeshClsn mMeshClsn; /* 0x144 */ + Model mModel; /* 0x300 */ + ShadowModel mShadowModel; /* 0x350 */ + MovingCylinderClsn mCylinderClsn2; /* 0x378 */ + void* mState; /* 0x3ac */ + /* Where it was spawned: InitResources copies mPos here verbatim, and + Behavior stashes mPrevAngleY into mSpawnAngleY when the shell is spat + back out of Yoshi's mouth. */ + s32 mSpawnPosX; /* 0x3b0 */ + s32 mSpawnPosY; /* 0x3b4 */ + s32 mSpawnPosZ; /* 0x3b8 */ + s16 mSpawnAngleY; /* 0x3bc */ + u8 pad_3be[0x2]; + s32 unk_3c0; /* 0x3c0 */ + /* Model index, 0 or 1, off bit 0 of mSpawnParam. Behavior gives index 0 a + per-frame call the other does not get. */ + u8 mModelIndex; /* 0x3c4 */ + u8 unk_3c5; /* 0x3c5 */ + /* Despawn countdown, and it only runs in one state. Render blinks the + shell while it is below 0x2d by skipping odd values, so the shell + flashes out rather than vanishing. */ + u8 mDespawnTimer; /* 0x3c6 */ + u8 pad_3c7[0x1]; + s32 unk_3c8; /* 0x3c8 */ + s32 unk_3cc; /* 0x3cc */ + s32 unk_3d0; /* 0x3d0 */ + s32 unk_3d4; /* 0x3d4 */ + + virtual ~KoopaShell(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + void OnPendingDestroy(); + int Render(); +}; + +#else + +/* The same object for a C translation unit, flat. */ struct KoopaShell { u8 pad_000[0x8]; /* Spawn parameter word. InitResources takes bit 0 as the model index into @@ -80,14 +128,8 @@ struct KoopaShell { s32 unk_3cc; /* 0x3cc */ s32 unk_3d0; /* 0x3d0 */ s32 unk_3d4; /* 0x3d4 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - void OnPendingDestroy(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* KOOPASHELL_H */ diff --git a/include/MeshCollider.h b/include/MeshCollider.h index 22afa018d..ac0b47272 100644 --- a/include/MeshCollider.h +++ b/include/MeshCollider.h @@ -70,6 +70,8 @@ struct KCL_File { u32 zShift; /* 0x34 */ }; +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct MeshCollider : MeshColliderBase { KCL_File *kclFile; /* 0x20 */ u32 clps; /* 0x24 - set via func_0203821c, released via func_02038224 */ @@ -123,6 +125,23 @@ struct MeshCollider : MeshColliderBase { /* --- static --- */ static char *LoadFile(SharedFilePtr &ptr); static void UpdateFileOffsets(KCL_File &file); + + /* WHAT LETS A REAL `~Class()` REPRODUCE THE ROM'S DELETING DESTRUCTOR. + The compiler generates D0 as "run the destructor body, then call operator + delete on the class". Without this it emits the global `_ZdlPv`, which + exists nowhere in this image, and the D0 comes out one relocated word + different from the ROM -- a difference build_pin.verify CANNOT SEE, + because it wildcards relocated words. Only the link catches it. + + This family deallocates through Memory::operator_delete2, not the actor + heap: every D0 below ends with a call to 0x0203cbcc. Actor's copy of this + member calls Memory::Deallocate instead, which is why each needs its own. + + Inline, and in the IMMEDIATE base -- mwcc inlines it only when it finds it + in the class or one level up, as include/Actor.h records. No layout + effect: a non-virtual inline member adds no field and no vtable slot. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; typedef char MeshCollider_size_must_be_0x50[sizeof(MeshCollider) == 0x50 ? 1 : -1]; diff --git a/include/MetalNet.h b/include/MetalNet.h index 742c5d6c9..fb2d1aba8 100644 --- a/include/MetalNet.h +++ b/include/MetalNet.h @@ -1,13 +1,41 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class MetalNet: 6 matched functions, 5 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef METALNET_H #define METALNET_H + #include "types.h" -#include "Model.h" -#include "MovingMeshCollider.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct MetalNet : Platform { + /* no fields of its own */ + + /* --- vtable --- */ + virtual ~MetalNet(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char MetalNet_size_must_be_0x320[sizeof(MetalNet) == 0x320 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct MetalNet { u8 pad_000[0x8]; s32 unk_008; /* 0x008 */ @@ -22,13 +50,8 @@ struct MetalNet { checks. Was a u8 marker. [_ZN8MetalNetD1Ev.c] */ MovingMeshCollider mMovingMeshCollider; /* 0x124 */ u8 unk_2ec; /* 0x2ec */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* METALNET_H */ diff --git a/include/Minimap.h b/include/Minimap.h index 87b3d425c..6521d5a66 100644 --- a/include/Minimap.h +++ b/include/Minimap.h @@ -1,11 +1,92 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class Minimap: 9 matched functions, 25 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef MINIMAP_H #define MINIMAP_H + #include "types.h" +#include "ActorDerived.h" + +/* Derives from ActorDerived: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x50 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +struct Minimap : ActorDerived { + s32 unk_050; /* 0x050 */ + s32 unk_054; /* 0x054 */ + s32 unk_058; /* 0x058 */ + s32 mPosX; /* 0x05c */ + s32 unk_060; /* 0x060 */ + s32 unk_064; /* 0x064 */ + u8 pad_068[0x8]; + s32 unk_070[4]; /* 0x070 */ + s32 unk_080[4]; /* 0x080 */ + s32 unk_090; /* 0x090 */ + s32 unk_094; /* 0x094 */ + s32 unk_098; /* 0x098 */ + s32 unk_09c; /* 0x09c */ + s32 unk_0a0[12]; /* 0x0a0 */ + s32 unk_0d0[12]; /* 0x0d0 */ + s32 unk_100[9]; /* 0x100 */ + s32 unk_124[9]; /* 0x124 */ + u8 pad_148[0x30]; + s32 unk_178; /* 0x178 */ + s32 unk_17c; /* 0x17c */ + s32 unk_180[8]; /* 0x180 */ + s32 unk_1a0[8]; /* 0x1a0 */ + u8 pad_1c0[0x14]; + s32 unk_1d4; /* 0x1d4 */ + s32 unk_1d8; /* 0x1d8 */ + s32 unk_1dc; /* 0x1dc */ + s32 unk_1e0; /* 0x1e0 */ + s32 unk_1e4; /* 0x1e4 */ + s32 unk_1e8; /* 0x1e8 */ + s32 unk_1ec; /* 0x1ec */ + s32 unk_1f0; /* 0x1f0 */ + s32 unk_1f4; /* 0x1f4 */ + s32 unk_1f8; /* 0x1f8 */ + s32 unk_1fc; /* 0x1fc */ + s32 unk_200; /* 0x200 */ + s32 unk_204; /* 0x204 */ + s32 unk_208; /* 0x208 */ + s32 unk_20c; /* 0x20c */ + s32 unk_210; /* 0x210 */ + s32 unk_214; /* 0x214 */ + s32 unk_218; /* 0x218 */ + u16 unk_21c; /* 0x21c */ + s8 unk_21e[4]; /* 0x21e */ + s8 unk_222[12]; /* 0x222 */ + u8 pad_22e[0xc]; + s8 unk_23a[9]; /* 0x23a */ + u8 pad_243[0x5]; + s8 unk_248; /* 0x248 */ + s8 unk_249[8]; /* 0x249 */ + u8 unk_251; /* 0x251 */ + u8 pad_252[0x2]; + u8 unk_254; /* 0x254 */ + u8 unk_255; /* 0x255 */ + + /* --- vtable --- */ + virtual ~Minimap(); + + int Behavior(); + static void FixTHIPaintingRoomPos(Vector3 & v_); + int InitResources(); + s32 CleanupResources(); + void OnPendingDestroy(); +}; + +typedef char Minimap_size_must_be_0x258[sizeof(Minimap) == 0x258 ? 1 : -1]; + +#else +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct Minimap { u8 pad_000[0x50]; s32 unk_050; /* 0x050 */ @@ -72,18 +153,8 @@ struct Minimap { u8 pad_252[0x2]; u8 unk_254; /* 0x254 */ u8 unk_255; /* 0x255 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - /* STATIC -- no `this`. The ROM keeps r0 (the Vector3) in r4 and clobbers r1 - before any use, so the only incoming pointer is the argument. Staticness - is not part of the mangling, so the symbol is unchanged either way; the - evidence is the register use. */ - static void FixTHIPaintingRoomPos(Vector3 & v_); - int InitResources(); - s32 CleanupResources(); - void OnPendingDestroy(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* MINIMAP_H */ diff --git a/include/ModelAnim.h b/include/ModelAnim.h index e4592beb1..b6ad7df5a 100644 --- a/include/ModelAnim.h +++ b/include/ModelAnim.h @@ -64,6 +64,8 @@ #ifdef __cplusplus +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct ModelAnim : Model, Animation { BCA_File *file; /* 0x60 */ @@ -78,6 +80,16 @@ struct ModelAnim : Model, Animation { void SetAnim(BCA_File *animFile, int flags, Fix12 speed, u32 startFrame); /* defined as a free function, wall 6az */ void Copy(const ModelAnim &src, char *newFile); + + /* ITS OWN, TO RESOLVE AN AMBIGUITY MULTIPLE INHERITANCE CREATES. ModelAnim + derives from Model (so ModelBase) and from Animation, and both bases + declare operator delete, so an inherited one is "ambiguous access to + name found: ModelBase::operator delete and Animation::operator delete". + Declaring it here picks the same deallocator both bases name, and also + satisfies the rule in include/Actor.h that mwcc only inlines the member + when it is in the class or its immediate base. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; typedef char ModelAnim_size_must_be_0x64[sizeof(ModelAnim) == 0x64 ? 1 : -1]; diff --git a/include/ModelAnim2.h b/include/ModelAnim2.h index e49ed0568..d0e31b9a0 100644 --- a/include/ModelAnim2.h +++ b/include/ModelAnim2.h @@ -21,6 +21,8 @@ #ifdef __cplusplus +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct ModelAnim2 : ModelAnim { u32 otherFile; /* 0x64 - the second animation's BCA, stored as a word */ Animation otherAnim; /* 0x68 - a member, built with Animation::C1 */ @@ -32,6 +34,16 @@ struct ModelAnim2 : ModelAnim { void Copy(const ModelAnim2 &src, char *newFile, u32 newOtherFile); void Func_020162C4(u32 animFile, int flags, Fix12 speed, u16 startFrame); /* free function, wall 6az */ + + /* ITS OWN, TO RESOLVE AN AMBIGUITY MULTIPLE INHERITANCE CREATES. ModelAnim + derives from Model (so ModelBase) and from Animation, and both bases + declare operator delete, so an inherited one is "ambiguous access to + name found: ModelBase::operator delete and Animation::operator delete". + Declaring it here picks the same deallocator both bases name, and also + satisfies the rule in include/Actor.h that mwcc only inlines the member + when it is in the class or its immediate base. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; typedef char ModelAnim2_size_must_be_0x78[sizeof(ModelAnim2) == 0x78 ? 1 : -1]; diff --git a/include/ModelBase.h b/include/ModelBase.h index c7a32dcd5..65dfdb897 100644 --- a/include/ModelBase.h +++ b/include/ModelBase.h @@ -78,6 +78,8 @@ struct ModelComponents { void Render(Matrix4x3 *mat, Vector3 *scale); /* 0x020443c8 */ }; +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct ModelBase { /* 0x00 is the vptr, placed implicitly by the first virtual declaration. */ BMD_File *modelFile; /* 0x04 - owned; the destructors Deallocate it */ @@ -87,8 +89,30 @@ struct ModelBase { virtual int DoSetFile(char *file, int a, int b) = 0; /* slot 2, null here */ /* --- non-virtual --- */ - void SetFile(BMD_File *file, int a, int b); /* dispatches DoSetFile */ + /* RETURNS int, not void. The definition at 0x02016fd4 is eight + instructions: load the vtable, `blx` slot 2 (DoSetFile, which returns + int), then the epilogue -- r0 is never touched after the call, so it + flows straight out. Callers corroborate: KoopaShell::InitResources tests + the result and bails on 0. */ + int SetFile(BMD_File *file, int a, int b); /* dispatches DoSetFile */ void ApplyOpacity(u32 a); + + /* WHAT LETS A REAL `~Class()` REPRODUCE THE ROM'S DELETING DESTRUCTOR. + The compiler generates D0 as "run the destructor body, then call operator + delete on the class". Without this it emits the global `_ZdlPv`, which + exists nowhere in this image, and the D0 comes out one relocated word + different from the ROM -- a difference build_pin.verify CANNOT SEE, + because it wildcards relocated words. Only the link catches it. + + This family deallocates through Memory::operator_delete2, not the actor + heap: every D0 below ends with a call to 0x0203cbcc. Actor's copy of this + member calls Memory::Deallocate instead, which is why each needs its own. + + Inline, and in the IMMEDIATE base -- mwcc inlines it only when it finds it + in the class or one level up, as include/Actor.h records. No layout + effect: a non-virtual inline member adds no field and no vtable slot. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; typedef char ModelComponents_size_must_be_0x14[sizeof(ModelComponents) == 0x14 ? 1 : -1]; diff --git a/include/MontyMoleRock.h b/include/MontyMoleRock.h index 42c117bd0..d355df6a1 100644 --- a/include/MontyMoleRock.h +++ b/include/MontyMoleRock.h @@ -1,14 +1,45 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class MontyMoleRock: 5 matched functions, 10 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef MONTYMOLEROCK_H #define MONTYMOLEROCK_H + #include "types.h" + +/* Derives from Enemy: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x110 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Enemy.h" #include "Model.h" #include "MovingCylinderClsn.h" #include "WithMeshClsn.h" +struct MontyMoleRock : Enemy { + Model mModel; /* 0x110 */ + MovingCylinderClsn mMovingCylinderClsn;/* 0x160 */ + WithMeshClsn mWithMeshClsn; /* 0x194 */ + u8 unk_350; /* 0x350 */ + + /* --- vtable --- */ + virtual ~MontyMoleRock(); + + virtual s32 Behavior(); + virtual s32 InitResources(); + virtual s32 Render(); +}; + +typedef char MontyMoleRock_size_must_be_0x354[sizeof(MontyMoleRock) == 0x354 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct MontyMoleRock { u8 pad_000[0x8]; s32 unk_008; /* 0x008 */ @@ -32,12 +63,8 @@ struct MontyMoleRock { checks. Was a u8 marker. [_ZN13MontyMoleRockD1Ev.c] */ WithMeshClsn mWithMeshClsn; /* 0x194 */ u8 unk_350; /* 0x350 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* MONTYMOLEROCK_H */ diff --git a/include/MovingBarSmall.h b/include/MovingBarSmall.h index 102670f3a..45a167993 100644 --- a/include/MovingBarSmall.h +++ b/include/MovingBarSmall.h @@ -1,12 +1,51 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class MovingBarSmall: 6 matched functions, 21 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef MOVINGBARSMALL_H #define MOVINGBARSMALL_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "ShadowModel.h" + +struct MovingBarSmall : Platform { + u8 pad_31e[0x2]; + ShadowModel mShadowModel; /* 0x320 */ + u8 pad_348[0x30]; + s32 unk_378; /* 0x378 */ + s32 unk_37c; /* 0x37c */ + s32 unk_380; /* 0x380 */ + s32 unk_384; /* 0x384 */ + s32 unk_388; /* 0x388 */ + s32 unk_38c; /* 0x38c */ + u8 unk_390; /* 0x390 */ + u8 unk_391; /* 0x391 */ + u8 unk_392; /* 0x392 */ + + /* --- vtable --- */ + virtual ~MovingBarSmall(); + + int CleanupResources(); + int Render(); +}; + +typedef char MovingBarSmall_size_must_be_0x394[sizeof(MovingBarSmall) == 0x394 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct MovingBarSmall { u8 pad_000[0x8]; s32 mParam; /* 0x008 */ @@ -41,11 +80,8 @@ struct MovingBarSmall { u8 unk_390; /* 0x390 */ u8 unk_391; /* 0x391 */ u8 unk_392; /* 0x392 */ -#ifdef __cplusplus - /* methods */ - int CleanupResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* MOVINGBARSMALL_H */ diff --git a/include/MovingCylinderClsn.h b/include/MovingCylinderClsn.h index 8cfc572d4..ce5092920 100644 --- a/include/MovingCylinderClsn.h +++ b/include/MovingCylinderClsn.h @@ -36,6 +36,8 @@ struct Actor; +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct MovingCylinderClsn : CylinderClsn { Actor *owner; /* 0x30 - nulled by C2 */ @@ -43,6 +45,23 @@ struct MovingCylinderClsn : CylinderClsn { virtual ~MovingCylinderClsn(); /* slots 0 (D1), 1 (D0) */ virtual Vector3 &GetPos(); /* slot 2 - the owner's pos, not ours */ virtual u32 GetOwnerID(); /* slot 3 - owner->uniqueID */ + + /* WHAT LETS A REAL `~Class()` REPRODUCE THE ROM'S DELETING DESTRUCTOR. + The compiler generates D0 as "run the destructor body, then call operator + delete on the class". Without this it emits the global `_ZdlPv`, which + exists nowhere in this image, and the D0 comes out one relocated word + different from the ROM -- a difference build_pin.verify CANNOT SEE, + because it wildcards relocated words. Only the link catches it. + + This family deallocates through Memory::operator_delete2, not the actor + heap: every D0 below ends with a call to 0x0203cbcc. Actor's copy of this + member calls Memory::Deallocate instead, which is why each needs its own. + + Inline, and in the IMMEDIATE base -- mwcc inlines it only when it finds it + in the class or one level up, as include/Actor.h records. No layout + effect: a non-virtual inline member adds no field and no vtable slot. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; typedef char MovingCylinderClsn_size_must_be_0x34[ diff --git a/include/MovingMeshCollider.h b/include/MovingMeshCollider.h index 7af21e595..c0e787784 100644 --- a/include/MovingMeshCollider.h +++ b/include/MovingMeshCollider.h @@ -27,6 +27,8 @@ #include "math/Fix12.h" +extern "C" void _ZN6Memory16operator_delete2EPv(void *); + struct MovingMeshCollider : MeshCollider { Fix12i scale; /* 0x50 */ Matrix4x3 mat; /* 0x54 */ @@ -62,6 +64,23 @@ struct MovingMeshCollider : MeshCollider { void SetFile(KCL_File *file, const Matrix4x3 &mat, Fix12 scale, s16 angY, CLPS_Block &clps); /* free def, wall 6az */ void Transform(const Matrix4x3 &mat, s16 angY); /* free def for now */ + + /* WHAT LETS A REAL `~Class()` REPRODUCE THE ROM'S DELETING DESTRUCTOR. + The compiler generates D0 as "run the destructor body, then call operator + delete on the class". Without this it emits the global `_ZdlPv`, which + exists nowhere in this image, and the D0 comes out one relocated word + different from the ROM -- a difference build_pin.verify CANNOT SEE, + because it wildcards relocated words. Only the link catches it. + + This family deallocates through Memory::operator_delete2, not the actor + heap: every D0 below ends with a call to 0x0203cbcc. Actor's copy of this + member calls Memory::Deallocate instead, which is why each needs its own. + + Inline, and in the IMMEDIATE base -- mwcc inlines it only when it finds it + in the class or one level up, as include/Actor.h records. No layout + effect: a non-virtual inline member adds no field and no vtable slot. */ + void operator delete(void *ptr) { _ZN6Memory16operator_delete2EPv(ptr); } + }; typedef char MovingMeshCollider_size_must_be_0x1c8[sizeof(MovingMeshCollider) == 0x1c8 ? 1 : -1]; diff --git a/include/MrBlizzard.h b/include/MrBlizzard.h index d27678cfb..ff301eb5e 100644 --- a/include/MrBlizzard.h +++ b/include/MrBlizzard.h @@ -1,14 +1,60 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class MrBlizzard: 5 matched functions, 29 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef MRBLIZZARD_H #define MRBLIZZARD_H + #include "types.h" + +/* Derives from Enemy: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x110 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Enemy.h" +#include "ModelAnim.h" #include "MovingCylinderClsnWithPos.h" +#include "ShadowModel.h" #include "WithMeshClsn.h" -#include "ModelAnim.h" +struct MrBlizzard : Enemy { + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos;/* 0x110 */ + WithMeshClsn mWithMeshClsn; /* 0x150 */ + ModelAnim mModelAnim; /* 0x30c */ + ShadowModel mShadowModel; /* 0x370 */ + u8 pad_398[0x64]; + s32 unk_3fc; /* 0x3fc */ + s32 unk_400; /* 0x400 */ + u8 pad_404[0x10]; + s16 unk_414; /* 0x414 */ + u8 pad_416[0x2]; + s32 mPathId; /* 0x418 */ + s32 mType; /* 0x41c */ + s32 unk_420; /* 0x420 */ + s32 unk_424; /* 0x424 */ + u8 pad_428[0x24]; + s32 unk_44c; /* 0x44c */ + s32 unk_450; /* 0x450 */ + s32 unk_454; /* 0x454 */ + + /* --- vtable --- */ + virtual ~MrBlizzard(); + + int Behavior(); + int InitResources(); + int Render(); +}; + +typedef char MrBlizzard_size_must_be_0x458[sizeof(MrBlizzard) == 0x458 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct MrBlizzard { u8 pad_000[0x8]; s32 mParam; /* 0x008 */ @@ -63,12 +109,8 @@ struct MrBlizzard { s32 unk_44c; /* 0x44c */ s32 unk_450; /* 0x450 */ s32 unk_454; /* 0x454 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* MRBLIZZARD_H */ diff --git a/include/PathLift.h b/include/PathLift.h index 32ef1e7a0..8cea414b4 100644 --- a/include/PathLift.h +++ b/include/PathLift.h @@ -1,11 +1,42 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class PathLift: 4 matched functions, 6 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef PATHLIFT_H #define PATHLIFT_H + #include "types.h" +/* A lift that runs along a path. Derives from Platform, and its own data starts + * in the base's tail padding at 0x31e (Platform's last field ends there and its + * size rounds to 0x320). + * + * THE ARRAY IS Model[3]. The ROM destroys it with + * __destroy_arr(this + 0x320, 3, 0x50, _ZN5ModelD1Ev) -- the element + * destructor is named in the ROM already, and 0x50 is sizeof(Model), so this + * one needed no new type at all. 0x320 + 3 * 0x50 = 0x410. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "Model.h" + +struct PathLift : Platform { + u8 pad_31e[0x2]; + Model mModels[3]; /* 0x320 */ + u8 pad_410[0x1a]; + u8 unk_42a; /* 0x42a */ + u8 unk_42b; /* 0x42b */ + u8 pad_42c[0x20]; + s32 unk_44c; /* 0x44c */ + + virtual ~PathLift(); + + void AfterClsn(); +}; + +typedef char PathLift_size_must_be_0x450[sizeof(PathLift) == 0x450 ? 1 : -1]; + +#else + +/* The same object for a C translation unit, flat. */ struct PathLift { u8 pad_000[0xc]; u16 unk_00c; /* 0x00c */ @@ -18,10 +49,8 @@ struct PathLift { u8 unk_42b; /* 0x42b */ u8 pad_42c[0x20]; s32 unk_44c; /* 0x44c */ -#ifdef __cplusplus - /* methods */ - void AfterClsn(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* PATHLIFT_H */ diff --git a/include/Platform.h b/include/Platform.h index 5589d4ac1..a1beff6a7 100644 --- a/include/Platform.h +++ b/include/Platform.h @@ -18,12 +18,27 @@ * (0x0d4 + 0x40 / +0x44 / +0x48). They were declared as siblings of a `u8 mModel` * marker whose pad stopped short of the real object. * - * The class's DATA ends at 0x31e, and that is not the same as its sizeof. A - * derived class's fields start at the base's data size rounded to their own - * alignment, so StarSwitch's first s32 lands at 0x320 and BowserFireSeaArena's - * first s16 lands at 0x31e. Claiming 0x31e..0x324 for Platform reproduces - * BowserFireSeaArena (its three s16 sit at the same addresses either way) and - * makes StarSwitch impossible, which is how the error was caught. + * SIZEOF IS 0x320, and it takes more than one derived class to see why. + * BowserFireSeaArena starts its own Model at 0x324, which alone reads like the + * class ending there. But FOUR classes derive from Platform DIRECTLY -- one + * non-Platform vtable store each, so no intermediate -- and each places a + * 4-byte-aligned CLASS member at 0x320, impossible if this class occupied + * 0x320..0x323: + * + * PyramidTop daObjDlPyramid_c Model @ 0x320 + * SwitchPillar daObjC0Water_c TextureTransformer @ 0x320 + * MovingBarSmall daObjBk_Lift_c ShadowModel @ 0x320 + * WallSign daObjKanban_c MovingCylinderClsnWithPos @ 0x320 + * + * Each is read straight off that class's destructor, which destroys its own + * member at 0x320 before storing _ZTV8Platform and running the base. + * + * One layout satisfies all five: data ends 0x31e, sizeof 0x320. The four above + * align up from 0x31e to 0x320; BowserFireSeaArena puts its OWN three s16 at + * 0x31e/0x320/0x322 so its Model lands at 0x324; DonutBlock puts a single s16 + * at 0x31e, in this class's tail padding, and its Behavior reads this+0x31e + * and reproduces. Ending at 0x324 satisfies BowserFireSeaArena and contradicts + * the other four. * * Field NAMES for the unk_ entries are placeholders. */ #ifndef PLATFORM_H @@ -66,6 +81,8 @@ struct Platform : Actor { Matrix4x3 mClsnMat; /* 0x2ec */ u8 unk_31c; /* 0x31c */ u8 unk_31d; /* 0x31d */ + /* THE CLASS ENDS HERE, at 0x31e; sizeof rounds to 0x320. See the header + comment: three s16 used to sit here, and they are BowserFireSeaArena's. */ /* --- vtable, in ROM order. Do not reorder. --- */ /* INLINE ON PURPOSE. Every Platform subclass's destructor inlines this body @@ -82,9 +99,6 @@ struct Platform : Actor { void UpdateModelPosAndRotY(); }; -/* 0x320, not 0x324: the last field ends at 0x31e and the class rounds up to its - 4-byte alignment. The DATA size is 0x31e, and that is what a derived class's - fields start from -- see the note above. */ typedef char Platform_size_must_be_0x320[sizeof(Platform) == 0x320 ? 1 : -1]; #else @@ -133,11 +147,7 @@ struct Platform { struct Matrix4x3 mClsnMat; /* 0x2ec */ u8 unk_31c; /* 0x31c */ u8 unk_31d; /* 0x31d */ - /* 0x31e..0x324: evidenced from BowserFireSeaArena, which reads all three and - whose own first member starts at 0x324. They are Platform's, not its. */ - s16 unk_31e; /* 0x31e */ - s16 unk_320; /* 0x320 */ - s16 unk_322; /* 0x322 */ + /* Ends at 0x31e; sizeof rounds to 0x320. See the C++ half. */ }; #endif /* __cplusplus */ diff --git a/include/PoleBillboard.h b/include/PoleBillboard.h index fd1fc5306..ea33dfe2f 100644 --- a/include/PoleBillboard.h +++ b/include/PoleBillboard.h @@ -1,12 +1,53 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class PoleBillboard: 6 matched functions, 19 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef POLEBILLBOARD_H #define POLEBILLBOARD_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "ShadowModel.h" + +struct PoleBillboard : Platform { + u8 pad_31e[0x2]; + ShadowModel mShadowModel; /* 0x320 */ + u8 pad_348[0x30]; + s32 unk_378; /* 0x378 */ + s32 unk_37c; /* 0x37c */ + s32 unk_380; /* 0x380 */ + s32 unk_384; /* 0x384 */ + s32 unk_388; /* 0x388 */ + s32 unk_38c; /* 0x38c */ + u16 unk_390; /* 0x390 */ + s16 unk_392; /* 0x392 */ + s16 unk_394; /* 0x394 */ + s8 unk_396; /* 0x396 */ + u8 unk_397; /* 0x397 */ + + /* --- vtable --- */ + virtual ~PoleBillboard(); + + int CleanupResources(); + int Render(); +}; + +typedef char PoleBillboard_size_must_be_0x398[sizeof(PoleBillboard) == 0x398 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct PoleBillboard { u8 pad_000[0x5c]; s32 mPosX; /* 0x05c */ @@ -34,11 +75,8 @@ struct PoleBillboard { s16 unk_394; /* 0x394 */ s8 unk_396; /* 0x396 */ u8 unk_397; /* 0x397 */ -#ifdef __cplusplus - /* methods */ - int CleanupResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* POLEBILLBOARD_H */ diff --git a/include/PyramidStep.h b/include/PyramidStep.h index 8342aa7f4..5e92a553d 100644 --- a/include/PyramidStep.h +++ b/include/PyramidStep.h @@ -1,12 +1,47 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class PyramidStep: 6 matched functions, 9 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef PYRAMIDSTEP_H #define PYRAMIDSTEP_H + #include "types.h" + +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" #include "Model.h" +struct PyramidStep : Platform { + u8 pad_31e[0x2]; + Model mModel; /* 0x320 */ + s16 unk_370; /* 0x370 */ + u8 unk_372; /* 0x372 */ + u8 pad_373[0x1]; + u8 unk_374; /* 0x374 */ + + /* --- vtable --- */ + virtual ~PyramidStep(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char PyramidStep_size_must_be_0x378[sizeof(PyramidStep) == 0x378 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct PyramidStep { u8 pad_000[0x8]; s32 unk_008; /* 0x008 */ @@ -28,13 +63,8 @@ struct PyramidStep { u8 unk_372; /* 0x372 */ u8 pad_373[0x1]; u8 unk_374; /* 0x374 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* PYRAMIDSTEP_H */ diff --git a/include/PyramidTop.h b/include/PyramidTop.h index 836c4237d..ce20fe889 100644 --- a/include/PyramidTop.h +++ b/include/PyramidTop.h @@ -1,12 +1,53 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class PyramidTop: 6 matched functions, 17 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef PYRAMIDTOP_H #define PYRAMIDTOP_H + #include "types.h" + +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" #include "Model.h" +struct PyramidTop : Platform { + u8 pad_31e[0x2]; + Model mModel; /* 0x320 */ + u8 pad_370[0x30]; + s32 unk_3a0; /* 0x3a0 */ + s32 unk_3a4; /* 0x3a4 */ + s32 unk_3a8; /* 0x3a8 */ + s32 unk_3ac; /* 0x3ac */ + s16 unk_3b0; /* 0x3b0 */ + u16 unk_3b2; /* 0x3b2 */ + s16 unk_3b4; /* 0x3b4 */ + u8 unk_3b6; /* 0x3b6 */ + u8 unk_3b7; /* 0x3b7 */ + + /* --- vtable --- */ + virtual ~PyramidTop(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char PyramidTop_size_must_be_0x3b8[sizeof(PyramidTop) == 0x3b8 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct PyramidTop { u8 pad_000[0x5c]; s32 mPosX; /* 0x05c */ @@ -45,13 +86,8 @@ struct PyramidTop { s16 unk_3b4; /* 0x3b4 */ u8 unk_3b6; /* 0x3b6 */ u8 unk_3b7; /* 0x3b7 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* PYRAMIDTOP_H */ diff --git a/include/QuestionBlock.h b/include/QuestionBlock.h index 7b9dc2186..ca7a5bd17 100644 --- a/include/QuestionBlock.h +++ b/include/QuestionBlock.h @@ -1,13 +1,54 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class QuestionBlock: 6 matched functions, 20 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef QUESTIONBLOCK_H #define QUESTIONBLOCK_H + #include "types.h" + +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" #include "ModelAnim.h" #include "ShadowModel.h" +struct QuestionBlock : Platform { + u8 pad_31e[0x2]; + ModelAnim mModelAnim; /* 0x320 */ + ShadowModel mShadowModel; /* 0x384 */ + u8 unk_3ac; /* 0x3ac */ + u8 pad_3ad[0x33]; + s32 unk_3e0; /* 0x3e0 */ + u8 pad_3e4[0x4]; + s32 unk_3e8; /* 0x3e8 */ + u8 pad_3ec[0x4]; + u8 unk_3f0; /* 0x3f0 */ + u8 unk_3f1; /* 0x3f1 */ + u8 pad_3f2[0x1]; + u8 unk_3f3; /* 0x3f3 */ + + /* --- vtable --- */ + virtual ~QuestionBlock(); + + int Behavior(); + int CleanupResources(); + int Render(); +}; + +typedef char QuestionBlock_size_must_be_0x3f4[sizeof(QuestionBlock) == 0x3f4 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct QuestionBlock { u8 pad_000[0x8]; s32 mParam; /* 0x008 */ @@ -48,12 +89,8 @@ struct QuestionBlock { u8 unk_3f1; /* 0x3f1 */ u8 pad_3f2[0x1]; u8 unk_3f3; /* 0x3f3 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* QUESTIONBLOCK_H */ diff --git a/include/RotatingCogSmall.h b/include/RotatingCogSmall.h index 969c0d234..81f17c23d 100644 --- a/include/RotatingCogSmall.h +++ b/include/RotatingCogSmall.h @@ -1,12 +1,46 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class RotatingCogSmall: 6 matched functions, 9 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef ROTATINGCOGSMALL_H #define ROTATINGCOGSMALL_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct RotatingCogSmall : Platform { + s16 unk_31e; /* 0x31e */ + s16 unk_320; /* 0x320 */ + s16 unk_322; /* 0x322 */ + s16 unk_324; /* 0x324 */ + u8 pad_326[0x6]; + s32 mRotationState; /* 0x32c */ + + /* --- vtable --- */ + virtual ~RotatingCogSmall(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char RotatingCogSmall_size_must_be_0x330[sizeof(RotatingCogSmall) == 0x330 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct RotatingCogSmall { u8 pad_000[0xc]; u16 unk_00c; /* 0x00c */ @@ -24,13 +58,8 @@ struct RotatingCogSmall { s16 unk_324; /* 0x324 */ u8 pad_326[0x6]; s32 mRotationState; /* 0x32c */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* ROTATINGCOGSMALL_H */ diff --git a/include/RotatingFirebar.h b/include/RotatingFirebar.h index 54e1fd2bf..83f50d443 100644 --- a/include/RotatingFirebar.h +++ b/include/RotatingFirebar.h @@ -1,12 +1,41 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class RotatingFirebar: 6 matched functions, 4 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef ROTATINGFIREBAR_H #define ROTATINGFIREBAR_H + #include "types.h" -#include "Model.h" +/* The rotating bar of flames. Derives from Platform, and the ONE thing it adds + * is the array of collision cylinders -- one per flame. + * + * CylinderClsnWithPos[8] 0x360 + 8 * 0x3c = 0x540 + * + * The ROM destroys it with + * __destroy_arr(this + 0x360, 8, 0x3c, _ZN19CylinderClsnWithPosD1Ev): 0x3c is + * sizeof(CylinderClsnWithPos) and the element destructor is a name the tree + * already had, so this class needed no new type. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "CylinderClsnWithPos.h" + +struct RotatingFirebar : Platform { + u8 pad_31e[0x42]; + CylinderClsnWithPos mCylinderClsns[8]; /* 0x360 */ + + virtual ~RotatingFirebar(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char RotatingFirebar_size_must_be_0x540[sizeof(RotatingFirebar) == 0x540 ? 1 : -1]; + +#else + +/* The same object for a C translation unit, flat. */ struct RotatingFirebar { u8 pad_000[0x8e]; s16 unk_08e; /* 0x08e */ @@ -15,15 +44,10 @@ struct RotatingFirebar { u8 pad_0b4[0x20]; /* Model member, named by _ZN5ModelD1Ev at +0xd4 -- a relocation the ROM build checks. D1 and not D2, so it is this type and not an inlined base. Was a u8 marker. */ - Model mModel; /* 0x0d4 */ + u8 mModel[0x50]; /* 0x0d4 */ u8 mMeshCollider; /* 0x124 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* ROTATINGFIREBAR_H */ diff --git a/include/RotatingPlatformLll.h b/include/RotatingPlatformLll.h index 1d6df78de..6b4461569 100644 --- a/include/RotatingPlatformLll.h +++ b/include/RotatingPlatformLll.h @@ -1,12 +1,43 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class RotatingPlatformLll: 6 matched functions, 6 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef ROTATINGPLATFORMLLL_H #define ROTATINGPLATFORMLLL_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct RotatingPlatformLll : Platform { + u8 pad_31e[0x2]; + s32 unk_320; /* 0x320 */ + u8 unk_324; /* 0x324 */ + + /* --- vtable --- */ + virtual ~RotatingPlatformLll(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char RotatingPlatformLll_size_must_be_0x328[sizeof(RotatingPlatformLll) == 0x328 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct RotatingPlatformLll { u8 pad_000[0x60]; s32 mPosY; /* 0x060 */ @@ -20,13 +51,8 @@ struct RotatingPlatformLll { u8 pad_125[0x1fb]; s32 unk_320; /* 0x320 */ u8 unk_324; /* 0x324 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* ROTATINGPLATFORMLLL_H */ diff --git a/include/RotatingPlatformWdw.h b/include/RotatingPlatformWdw.h index 0a50a259d..17bf8abc9 100644 --- a/include/RotatingPlatformWdw.h +++ b/include/RotatingPlatformWdw.h @@ -1,12 +1,50 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class RotatingPlatformWdw: 6 matched functions, 15 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef ROTATINGPLATFORMWDW_H #define ROTATINGPLATFORMWDW_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "TextureTransformer.h" + +struct RotatingPlatformWdw : Platform { + u8 pad_31e[0x2]; + TextureTransformer mTextureTransformer;/* 0x320 */ + s32 mTargetPosY; /* 0x334 */ + u8 unk_338; /* 0x338 */ + u8 pad_339[0x3]; + s32 unk_33c; /* 0x33c */ + u8 unk_340; /* 0x340 */ + u8 pad_341[0x3]; + s32 unk_344; /* 0x344 */ + + /* --- vtable --- */ + virtual ~RotatingPlatformWdw(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char RotatingPlatformWdw_size_must_be_0x348[sizeof(RotatingPlatformWdw) == 0x348 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct RotatingPlatformWdw { u8 pad_000[0x8]; s32 mParam; /* 0x008 */ @@ -37,13 +75,8 @@ struct RotatingPlatformWdw { u8 unk_340; /* 0x340 */ u8 pad_341[0x3]; s32 unk_344; /* 0x344 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* ROTATINGPLATFORMWDW_H */ diff --git a/include/SeesawBob.h b/include/SeesawBob.h index 5175032e2..81b039cbc 100644 --- a/include/SeesawBob.h +++ b/include/SeesawBob.h @@ -1,12 +1,44 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class SeesawBob: 6 matched functions, 9 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef SEESAWBOB_H #define SEESAWBOB_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct SeesawBob : Platform { + u8 pad_31e[0x2]; + s32 unk_320; /* 0x320 */ + s16 unk_324; /* 0x324 */ + u8 unk_326; /* 0x326 */ + + /* --- vtable --- */ + virtual ~SeesawBob(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char SeesawBob_size_must_be_0x328[sizeof(SeesawBob) == 0x328 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct SeesawBob { u8 pad_000[0xc]; u16 unk_00c; /* 0x00c */ @@ -24,13 +56,8 @@ struct SeesawBob { s32 unk_320; /* 0x320 */ s16 unk_324; /* 0x324 */ u8 unk_326; /* 0x326 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* SEESAWBOB_H */ diff --git a/include/ShadowModel.h b/include/ShadowModel.h index 7d16158e8..d5e3ceb2d 100644 --- a/include/ShadowModel.h +++ b/include/ShadowModel.h @@ -60,7 +60,9 @@ struct ShadowModel : ModelBase { /* --- non-virtual --- */ void InitModel(Matrix4x3 *m, Fix12 sx, Fix12 sy, Fix12 sz, u32 opacity); /* defined as a free function, see above */ - void InitCylinder(); + /* RETURNS int, not void: 0x02015ebc ends in `bx ip`, a tail call, so the + callee's r0 is this function's. Same evidence as ModelBase::SetFile. */ + int InitCylinder(); void InitCuboid(); /* --- static --- */ diff --git a/include/Shark.h b/include/Shark.h index e1e60a27b..56483ed68 100644 --- a/include/Shark.h +++ b/include/Shark.h @@ -1,14 +1,52 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class Shark: 5 matched functions, 24 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef SHARK_H #define SHARK_H + #include "types.h" + +/* Derives from Enemy: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x110 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Enemy.h" #include "ModelAnim.h" #include "MovingCylinderClsnWithPos.h" #include "WithMeshClsn.h" +struct Shark : Enemy { + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos;/* 0x110 */ + WithMeshClsn mWithMeshClsn; /* 0x150 */ + ModelAnim mModelAnim; /* 0x30c */ + s32 unk_370; /* 0x370 */ + s32 unk_374; /* 0x374 */ + s32 unk_378; /* 0x378 */ + s32 unk_37c; /* 0x37c */ + u8 pad_380[0x8]; + s32 mPathID; /* 0x388 */ + s32 unk_38c; /* 0x38c */ + s32 mPathNodeIdx; /* 0x390 */ + + /* --- vtable --- */ + virtual ~Shark(); + + int Behavior(); + int InitResources(); + int Render(); +}; + +typedef char Shark_size_must_be_0x394[sizeof(Shark) == 0x394 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct Shark { u8 pad_000[0x8]; s32 mParam; /* 0x008 */ @@ -62,12 +100,8 @@ struct Shark { s32 mPathID; /* 0x388 */ s32 unk_38c; /* 0x38c */ s32 mPathNodeIdx; /* 0x390 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* SHARK_H */ diff --git a/include/ShipWater.h b/include/ShipWater.h index 5cfa4c8c3..9b704f0a1 100644 --- a/include/ShipWater.h +++ b/include/ShipWater.h @@ -1,12 +1,47 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class ShipWater: 6 matched functions, 10 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef SHIPWATER_H #define SHIPWATER_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "TextureTransformer.h" + +struct ShipWater : Platform { + u8 pad_31e[0x2]; + TextureTransformer mTextureTransformer;/* 0x320 */ + s32 unk_334; /* 0x334 */ + u8 unk_338; /* 0x338 */ + u8 pad_339[0x3]; + s32 unk_33c; /* 0x33c */ + + /* --- vtable --- */ + virtual ~ShipWater(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char ShipWater_size_must_be_0x340[sizeof(ShipWater) == 0x340 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct ShipWater { u8 pad_000[0x60]; s32 mPosY; /* 0x060 */ @@ -50,13 +85,8 @@ struct ShipWater { u8 unk_338; /* 0x338 */ u8 pad_339[0x3]; s32 unk_33c; /* 0x33c */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* SHIPWATER_H */ diff --git a/include/ShipWing.h b/include/ShipWing.h index 6cc3306cb..992e9ac75 100644 --- a/include/ShipWing.h +++ b/include/ShipWing.h @@ -1,13 +1,49 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class ShipWing: 6 matched functions, 16 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef SHIPWING_H #define SHIPWING_H + #include "types.h" -#include "Model.h" + +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" #include "WithMeshClsn.h" +struct ShipWing : Platform { + u8 pad_31e[0x2]; + WithMeshClsn mWithMeshClsn; /* 0x320 */ + s32 unk_4dc; /* 0x4dc */ + s32 unk_4e0; /* 0x4e0 */ + s32 unk_4e4; /* 0x4e4 */ + u8 unk_4e8; /* 0x4e8 */ + u8 unk_4e9; /* 0x4e9 */ + u8 mState; /* 0x4ea */ + + /* --- vtable --- */ + virtual ~ShipWing(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char ShipWing_size_must_be_0x4ec[sizeof(ShipWing) == 0x4ec ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct ShipWing { u8 pad_000[0x5c]; s32 mPosX; /* 0x05c */ @@ -36,13 +72,8 @@ struct ShipWing { u8 unk_4e8; /* 0x4e8 */ u8 unk_4e9; /* 0x4e9 */ u8 mState; /* 0x4ea */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* SHIPWING_H */ diff --git a/include/SlidingIce.h b/include/SlidingIce.h index c17a9914a..f4ae1b2ca 100644 --- a/include/SlidingIce.h +++ b/include/SlidingIce.h @@ -1,12 +1,44 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class SlidingIce: 6 matched functions, 15 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef SLIDINGICE_H #define SLIDINGICE_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct SlidingIce : Platform { + s16 unk_31e; /* 0x31e */ + s8 unk_320; /* 0x320 */ + u8 pad_321[0x3]; + s32 unk_324; /* 0x324 */ + s32 unk_328; /* 0x328 */ + + /* --- vtable --- */ + virtual ~SlidingIce(); + + int Behavior(); + int CleanupResources(); + int Render(); +}; + +typedef char SlidingIce_size_must_be_0x32c[sizeof(SlidingIce) == 0x32c ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct SlidingIce { u8 pad_000[0xc]; u16 mActorID; /* 0x00c */ @@ -35,12 +67,8 @@ struct SlidingIce { u8 pad_321[0x3]; s32 unk_324; /* 0x324 */ s32 unk_328; /* 0x328 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* SLIDINGICE_H */ diff --git a/include/SlidingPlatformWf.h b/include/SlidingPlatformWf.h index 2ec09c977..71eda5da9 100644 --- a/include/SlidingPlatformWf.h +++ b/include/SlidingPlatformWf.h @@ -1,12 +1,44 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class SlidingPlatformWf: 6 matched functions, 5 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef SLIDINGPLATFORMWF_H #define SLIDINGPLATFORMWF_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct SlidingPlatformWf : Platform { + u8 unk_31e; /* 0x31e */ + u8 pad_31f[0x1]; + s16 unk_320; /* 0x320 */ + u8 unk_322; /* 0x322 */ + + /* --- vtable --- */ + virtual ~SlidingPlatformWf(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char SlidingPlatformWf_size_must_be_0x324[sizeof(SlidingPlatformWf) == 0x324 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct SlidingPlatformWf { u8 pad_000[0xd4]; /* Model member, named by _ZN5ModelD1Ev at +0xd4 -- a relocation the ROM build checks. @@ -18,13 +50,8 @@ struct SlidingPlatformWf { u8 pad_31f[0x1]; s16 unk_320; /* 0x320 */ u8 unk_322; /* 0x322 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* SLIDINGPLATFORMWF_H */ diff --git a/include/SquarePathLift.h b/include/SquarePathLift.h index c4b62fb91..ea65a677e 100644 --- a/include/SquarePathLift.h +++ b/include/SquarePathLift.h @@ -1,12 +1,45 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class SquarePathLift: 6 matched functions, 11 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef SQUAREPATHLIFT_H #define SQUAREPATHLIFT_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct SquarePathLift : Platform { + u8 pad_31e[0x2]; + u8 mPath; /* 0x320 */ + u8 pad_321[0x7]; + s32 mNodeIndex; /* 0x328 */ + s32 mPathDir; /* 0x32c */ + + /* --- vtable --- */ + virtual ~SquarePathLift(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char SquarePathLift_size_must_be_0x330[sizeof(SquarePathLift) == 0x330 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct SquarePathLift { u8 pad_000[0x8]; s32 mParam; /* 0x008 */ @@ -28,13 +61,8 @@ struct SquarePathLift { u8 pad_321[0x7]; s32 mNodeIndex; /* 0x328 */ s32 mPathDir; /* 0x32c */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* SQUAREPATHLIFT_H */ diff --git a/include/Squasher.h b/include/Squasher.h index bc0113ae2..3640d6839 100644 --- a/include/Squasher.h +++ b/include/Squasher.h @@ -1,13 +1,45 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class Squasher: 6 matched functions, 13 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef SQUASHER_H #define SQUASHER_H + #include "types.h" -#include "Model.h" -#include "MovingMeshCollider.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "ShadowModel.h" + +struct Squasher : Platform { + s16 unk_31e; /* 0x31e */ + s16 unk_320; /* 0x320 */ + u8 unk_322; /* 0x322 */ + u8 pad_323[0x1]; + ShadowModel mShadowModel; /* 0x324 */ + + /* --- vtable --- */ + virtual ~Squasher(); + + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char Squasher_size_must_be_0x34c[sizeof(Squasher) == 0x34c ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct Squasher { u8 pad_000[0x5c]; s32 mPosX; /* 0x05c */ @@ -39,12 +71,8 @@ struct Squasher { u8 unk_322; /* 0x322 */ u8 pad_323[0x1]; u8 mShadowModel; /* 0x324 */ -#ifdef __cplusplus - /* methods */ - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* SQUASHER_H */ diff --git a/include/StarSwitch.h b/include/StarSwitch.h index d1c54ba6d..e426696a8 100644 --- a/include/StarSwitch.h +++ b/include/StarSwitch.h @@ -2,25 +2,23 @@ #define STARSWITCH_H #include "types.h" -#include "Platform.h" /* Derives from Platform: the destructor stores this class's vtable, then - * Platform's -- inlined -- and then destroys the MovingMeshCollider at 0x124 - * and the Model at 0xd4 before chaining to Actor. Those three are Platform's - * and are declared there; everything this header used to restate below 0x31e - * was Actor's and Platform's. - * - * Any field at 0x31e or 0x31f sits in Platform's tail padding, which the - * Itanium ABI lets a derived class use because Platform is non-POD: its last - * field ends at 0x31e and its size rounds to 0x320. + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. * - * SIZE IS THE OBSERVED FIELD SPAN, rounded up -- not independent evidence. It - * is a regression guard on this declaration, not a claim about the ROM. + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. */ #ifdef __cplusplus +#include "Platform.h" + struct StarSwitch : Platform { + u8 pad_31e[0x2]; s32 unk_320; /* 0x320 */ s32 unk_324; /* 0x324 */ s32 unk_328; /* 0x328 */ @@ -51,6 +49,69 @@ struct StarSwitch : Platform { typedef char StarSwitch_size_must_be_0x354[sizeof(StarSwitch) == 0x354 ? 1 : -1]; +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ +struct StarSwitch { + u8 pad_000[0x8]; + u32 mParam; /* 0x008 */ + u16 mActorID; /* 0x00c */ + u8 pad_00e[0x52]; + /* 0x060..0x08e is Actor's, and Actor.h is de-bannered -- hand-reconstructed, not generated. Was one u8 + marker over the whole range. */ + s32 unk_060; /* 0x060 */ + s32 mPosZ; /* 0x064 */ + s32 unk_068; /* 0x068 */ + s32 unk_06c; /* 0x06c */ + s32 unk_070; /* 0x070 */ + s32 mCamSpacePosX; /* 0x074 */ + s32 mCamSpacePosY; /* 0x078 */ + s32 mCamSpacePosZ; /* 0x07c */ + s32 mScaleX; /* 0x080 */ + s32 mScaleY; /* 0x084 */ + s32 mScaleZ; /* 0x088 */ + s16 mAngleX; /* 0x08c */ + s16 mAngleY; /* 0x08e */ + u8 pad_090[0x20]; + /* 0x0b0..0x0cc is Actor's, and Actor.h is de-bannered -- hand-reconstructed, not generated. Was one u8 + marker over the whole range. */ + u32 unk_0b0; /* 0x0b0 */ + s32 unk_0b4; /* 0x0b4 */ + s32 unk_0b8; /* 0x0b8 */ + s32 unk_0bc; /* 0x0bc */ + s32 unk_0c0; /* 0x0c0 */ + u8 unk_0c4; /* 0x0c4 */ + u8 pad_0c5[0x7]; + u8 mAreaId; /* 0x0cc */ + u8 pad_0cd[0x7]; + /* Model member, named by _ZN5ModelD1Ev at +0xd4 -- a relocation the ROM build checks. + D1 and not D2, so it is this type and not an inlined base. Was a u8 marker. */ + Model mModel; /* 0x0d4 */ + u8 mMeshCollider; /* 0x124 */ + u8 pad_125[0x1fb]; + s32 unk_320; /* 0x320 */ + s32 unk_324; /* 0x324 */ + s32 unk_328; /* 0x328 */ + u8 pad_32c[0x8]; + s32 unk_334; /* 0x334 */ + s16 unk_338; /* 0x338 */ + u16 unk_33a; /* 0x33a */ + s32 unk_33c; /* 0x33c */ + u8 pad_340[0x4]; + u32 mTargetActorID; /* 0x344 */ + s32 unk_348; /* 0x348 */ + u8 unk_34c; /* 0x34c */ + u8 unk_34d; /* 0x34d */ + u8 unk_34e; /* 0x34e */ + u8 unk_34f; /* 0x34f */ + u8 unk_350; /* 0x350 */ + u8 unk_351; /* 0x351 */ + u8 pad_352[0x1]; + s8 unk_353; /* 0x353 */ +}; + #endif /* __cplusplus */ #endif /* STARSWITCH_H */ diff --git a/include/Stump.h b/include/Stump.h index 5f23d4149..211cf127e 100644 --- a/include/Stump.h +++ b/include/Stump.h @@ -1,13 +1,47 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class Stump: 6 matched functions, 8 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef STUMP_H #define STUMP_H + #include "types.h" + +/* Derives from Enemy: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x110 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Enemy.h" +#include "ModelAnim.h" #include "MovingCylinderClsn.h" #include "WithMeshClsn.h" +struct Stump : Enemy { + MovingCylinderClsn mMovingCylinderClsn;/* 0x110 */ + WithMeshClsn mWithMeshClsn; /* 0x144 */ + ModelAnim mModelAnim; /* 0x300 */ + u8 pad_364[0x10]; + s32 mVariant; /* 0x374 */ + + /* --- vtable --- */ + virtual ~Stump(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char Stump_size_must_be_0x378[sizeof(Stump) == 0x378 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct Stump { u8 pad_000[0x8]; s32 unk_008; /* 0x008 */ @@ -29,13 +63,8 @@ struct Stump { s32 unk_35c; /* 0x35c */ u8 pad_360[0x14]; s32 mVariant; /* 0x374 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* STUMP_H */ diff --git a/include/SwitchPillar.h b/include/SwitchPillar.h index 27d3a253f..209146f8b 100644 --- a/include/SwitchPillar.h +++ b/include/SwitchPillar.h @@ -1,12 +1,48 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class SwitchPillar: 6 matched functions, 12 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef SWITCHPILLAR_H #define SWITCHPILLAR_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "TextureTransformer.h" + +struct SwitchPillar : Platform { + u8 pad_31e[0x2]; + TextureTransformer mTextureTransformer;/* 0x320 */ + s32 mLoweredY; /* 0x334 */ + u32 unk_338; /* 0x338 */ + u8 unk_33c; /* 0x33c */ + u8 pad_33d[0x1]; + u8 unk_33e; /* 0x33e */ + + /* --- vtable --- */ + virtual ~SwitchPillar(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char SwitchPillar_size_must_be_0x340[sizeof(SwitchPillar) == 0x340 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct SwitchPillar { u8 pad_000[0x60]; s32 mPosY; /* 0x060 */ @@ -38,13 +74,8 @@ struct SwitchPillar { u8 unk_33c; /* 0x33c */ u8 pad_33d[0x1]; u8 unk_33e; /* 0x33e */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* SWITCHPILLAR_H */ diff --git a/include/TTC_MovingBar.h b/include/TTC_MovingBar.h index 487931599..945e3b77b 100644 --- a/include/TTC_MovingBar.h +++ b/include/TTC_MovingBar.h @@ -1,12 +1,44 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class TTC_MovingBar: 5 matched functions, 10 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef TTC_MOVINGBAR_H #define TTC_MOVINGBAR_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "ShadowModel.h" + +struct TTC_MovingBar : Platform { + u8 unk_31e; /* 0x31e */ + u8 pad_31f[0x1]; + s32 unk_320; /* 0x320 */ + ShadowModel mShadowModel; /* 0x324 */ + + /* --- vtable --- */ + virtual ~TTC_MovingBar(); + + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char TTC_MovingBar_size_must_be_0x34c[sizeof(TTC_MovingBar) == 0x34c ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct TTC_MovingBar { u8 pad_000[0xc]; u16 mActorID; /* 0x00c */ @@ -26,12 +58,8 @@ struct TTC_MovingBar { u8 pad_31f[0x1]; s32 unk_320; /* 0x320 */ u8 mShadowModel; /* 0x324 */ -#ifdef __cplusplus - /* methods */ - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* TTC_MOVINGBAR_H */ diff --git a/include/TinyCover.h b/include/TinyCover.h index 5ec944b1d..9f7d2cf34 100644 --- a/include/TinyCover.h +++ b/include/TinyCover.h @@ -1,13 +1,46 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class TinyCover: 6 matched functions, 8 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef TINYCOVER_H #define TINYCOVER_H + #include "types.h" -#include "Model.h" + +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" #include "TextureTransformer.h" +struct TinyCover : Platform { + u8 pad_31e[0x2]; + TextureTransformer mTextureTransformer;/* 0x320 */ + s32 unk_334; /* 0x334 */ + u8 pad_338[0x4]; + u8 unk_33c; /* 0x33c */ + + /* --- vtable --- */ + virtual ~TinyCover(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char TinyCover_size_must_be_0x340[sizeof(TinyCover) == 0x340 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct TinyCover { u8 pad_000[0x60]; s32 mPosY; /* 0x060 */ @@ -28,13 +61,8 @@ struct TinyCover { s32 unk_334; /* 0x334 */ u8 pad_338[0x4]; u8 unk_33c; /* 0x33c */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* TINYCOVER_H */ diff --git a/include/TowerStep.h b/include/TowerStep.h index a2eec2a8a..af259b68d 100644 --- a/include/TowerStep.h +++ b/include/TowerStep.h @@ -1,12 +1,43 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class TowerStep: 6 matched functions, 7 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef TOWERSTEP_H #define TOWERSTEP_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct TowerStep : Platform { + s8 unk_31e; /* 0x31e */ + u8 pad_31f[0x1]; + s32 unk_320; /* 0x320 */ + + /* --- vtable --- */ + virtual ~TowerStep(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char TowerStep_size_must_be_0x324[sizeof(TowerStep) == 0x324 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct TowerStep { u8 pad_000[0x74]; /* 0x074..0x08e is Actor's, and Actor.h is de-bannered -- hand-reconstructed, not generated. Was one u8 @@ -30,13 +61,8 @@ struct TowerStep { s8 unk_31e; /* 0x31e */ u8 pad_31f[0x1]; s32 unk_320; /* 0x320 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* TOWERSTEP_H */ diff --git a/include/TtcMovingCubeA.h b/include/TtcMovingCubeA.h index e79ca7c1d..a2d97ebff 100644 --- a/include/TtcMovingCubeA.h +++ b/include/TtcMovingCubeA.h @@ -1,13 +1,47 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class TtcMovingCubeA: 5 matched functions, 15 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef TTCMOVINGCUBEA_H #define TTCMOVINGCUBEA_H + #include "types.h" -#include "Model.h" -#include "MovingMeshCollider.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "ShadowModel.h" + +struct TtcMovingCubeA : Platform { + u8 pad_31e[0x2]; + s32 unk_320; /* 0x320 */ + s32 unk_324; /* 0x324 */ + u8 unk_328; /* 0x328 */ + u8 pad_329[0x7]; + s32 unk_330; /* 0x330 */ + ShadowModel mShadowModel; /* 0x334 */ + + /* --- vtable --- */ + virtual ~TtcMovingCubeA(); + + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char TtcMovingCubeA_size_must_be_0x35c[sizeof(TtcMovingCubeA) == 0x35c ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct TtcMovingCubeA { u8 pad_000[0x8]; s32 mParam; /* 0x008 */ @@ -37,12 +71,8 @@ struct TtcMovingCubeA { u8 pad_329[0x7]; s32 unk_330; /* 0x330 */ u8 mShadowModel; /* 0x334 */ -#ifdef __cplusplus - /* methods */ - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* TTCMOVINGCUBEA_H */ diff --git a/include/TtcRotatingGear.h b/include/TtcRotatingGear.h index 43582243e..b772ec0f6 100644 --- a/include/TtcRotatingGear.h +++ b/include/TtcRotatingGear.h @@ -1,12 +1,46 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class TtcRotatingGear: 6 matched functions, 13 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef TTCROTATINGGEAR_H #define TTCROTATINGGEAR_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" + +struct TtcRotatingGear : Platform { + u8 pad_31e[0x2]; + s32 unk_320; /* 0x320 */ + s32 unk_324; /* 0x324 */ + s32 unk_328; /* 0x328 */ + u16 unk_32c; /* 0x32c */ + u8 mMoveDir; /* 0x32e */ + + /* --- vtable --- */ + virtual ~TtcRotatingGear(); + + int Behavior(); + int CleanupResources(); + int InitResources(); + int Render(); +}; + +typedef char TtcRotatingGear_size_must_be_0x330[sizeof(TtcRotatingGear) == 0x330 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct TtcRotatingGear { u8 pad_000[0x5c]; s32 mPosX; /* 0x05c */ @@ -29,13 +63,8 @@ struct TtcRotatingGear { s32 unk_328; /* 0x328 */ u16 unk_32c; /* 0x32c */ u8 mMoveDir; /* 0x32e */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int CleanupResources(); - int InitResources(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* TTCROTATINGGEAR_H */ diff --git a/include/Unagi.h b/include/Unagi.h index 33fb8a1a4..93307af14 100644 --- a/include/Unagi.h +++ b/include/Unagi.h @@ -1,11 +1,79 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class Unagi: 5 matched functions, 38 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef UNAGI_H #define UNAGI_H + #include "types.h" +/* The eel. Its destructor is the layout, and every member closes exactly on + * the next field: + * + * Enemy ends 0x110 + * MovingCylinderClsnWithPos 0x110 + 0x040 = 0x150 -> the second one + * MovingCylinderClsnWithPos 0x150 + 0x040 = 0x190 -> WithMeshClsn + * WithMeshClsn 0x190 + 0x1bc = 0x34c -> unk_34c + * BlendModelAnim 0x350 + 0x070 = 0x3c0 + * Vector3[7] 0x448 + 0x054 = 0x49c -> mStarUniqueID + * + * unk_360 and unk_3ac are gone: both fall INSIDE the BlendModelAnim at 0x350 + * (+0x10 and +0x5c), so they were never Unagi's fields -- the generated header + * declared them beside a `u8 mBlendModelAnim` marker whose padding stopped + * short of the real object. + * + * The array at 0x448 is Vector3[7]: the ROM destroys it with + * __destroy_arr(ptr, 7, 0xc, _ZN7Vector3D1Ev), and 0xc is sizeof(Vector3). + */ + +#ifdef __cplusplus + +#include "Enemy.h" +#include "BlendModelAnim.h" +#include "WithMeshClsn.h" +#include "MovingCylinderClsnWithPos.h" + +struct Unagi : Enemy { + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos1; /* 0x110 */ + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos2; /* 0x150 */ + WithMeshClsn mWithMeshClsn; /* 0x190 */ + s32 unk_34c; /* 0x34c */ + BlendModelAnim mBlendModelAnim; /* 0x350 */ + s32 unk_3c0; /* 0x3c0 */ + u8 pad_3c4[0x2c]; + s32 unk_3f0; /* 0x3f0 */ + s32 unk_3f4; /* 0x3f4 */ + s32 unk_3f8; /* 0x3f8 */ + u8 pad_3fc[0x8]; + s32 mPathID; /* 0x404 */ + s32 mVariant; /* 0x408 */ + s32 unk_40c; /* 0x40c */ + s32 unk_410; /* 0x410 */ + u8 unk_414; /* 0x414 */ + u8 pad_415[0x3]; + u8 unk_418; /* 0x418 */ + u8 pad_419[0xd]; + u8 unk_426; /* 0x426 */ + u8 pad_427[0x1]; + s16 unk_428; /* 0x428 */ + s16 unk_42a; /* 0x42a */ + s16 unk_42c; /* 0x42c */ + u8 pad_42e[0xe]; + s32 unk_43c; /* 0x43c */ + s32 unk_440; /* 0x440 */ + s32 unk_444; /* 0x444 */ + Vector3 unk_448[7]; /* 0x448 */ + s32 mStarUniqueID; /* 0x49c */ + + virtual ~Unagi(); + + virtual s32 InitResources(); + virtual s32 CleanupResources(); + virtual s32 Behavior(); + virtual s32 Render(); +}; + +#else + +/* The same object for a C translation unit, flat -- Render and D0 are C files + that read these fields, and D0 is compiler-generated so it can never be + migrated. Same arrangement as include/Platform.h. */ struct Unagi { u8 pad_000[0x8]; u32 mParam; /* 0x008 */ @@ -65,11 +133,8 @@ struct Unagi { s32 unk_444; /* 0x444 */ u8 pad_448[0x54]; s32 mStarUniqueID; /* 0x49c */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int InitResources(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* UNAGI_H */ diff --git a/include/WallSign.h b/include/WallSign.h index dea63ac06..9b8609a93 100644 --- a/include/WallSign.h +++ b/include/WallSign.h @@ -1,12 +1,43 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class WallSign: 4 matched functions, 3 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef WALLSIGN_H #define WALLSIGN_H + #include "types.h" -#include "Model.h" +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Platform.h" +#include "MovingCylinderClsnWithPos.h" + +struct WallSign : Platform { + u8 pad_31e[0x2]; + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos;/* 0x320 */ + + /* --- vtable --- */ + virtual ~WallSign(); + + int CleanupResources(); + int InitResources(); + int Behavior(); + int Render(); +}; + +typedef char WallSign_size_must_be_0x360[sizeof(WallSign) == 0x360 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct WallSign { u8 pad_000[0xd4]; /* Model member, named by _ZN5ModelD1Ev at +0xd4 -- a relocation the ROM build checks. @@ -15,13 +46,8 @@ struct WallSign { u8 mMovingMeshCollider; /* 0x124 */ u8 pad_125[0x1fb]; u8 mMovingCylinderClsnWithPos; /* 0x320 */ -#ifdef __cplusplus - /* methods */ - int CleanupResources(); - int InitResources(); - int Behavior(); - int Render(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* WALLSIGN_H */ diff --git a/include/WaterSuction.h b/include/WaterSuction.h index 29a4d16ae..fcbb1e50a 100644 --- a/include/WaterSuction.h +++ b/include/WaterSuction.h @@ -1,12 +1,43 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class WaterSuction: 4 matched functions, 11 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef WATERSUCTION_H #define WATERSUCTION_H + #include "types.h" + +/* Derives from Enemy: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x110 belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +#include "Enemy.h" #include "MovingCylinderClsnWithPos.h" +#include "WithMeshClsn.h" +struct WaterSuction : Enemy { + MovingCylinderClsnWithPos mMovingCylinderClsnWithPos;/* 0x110 */ + WithMeshClsn mWithMeshClsn; /* 0x150 */ + u8 pad_30c[0x8]; + s32 unk_314; /* 0x314 */ + + /* --- vtable --- */ + virtual ~WaterSuction(); + + int Behavior(); + int InitResources(); +}; + +typedef char WaterSuction_size_must_be_0x318[sizeof(WaterSuction) == 0x318 ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ struct WaterSuction { u8 pad_000[0x8]; s32 unk_008; /* 0x008 */ @@ -27,11 +58,8 @@ struct WaterSuction { u8 mWithMeshClsn; /* 0x150 */ u8 pad_151[0x1c3]; s32 unk_314; /* 0x314 */ -#ifdef __cplusplus - /* methods */ - int Behavior(); - int InitResources(); -#endif }; -#endif +#endif /* __cplusplus */ + +#endif /* WATERSUCTION_H */ diff --git a/include/Wiggler.h b/include/Wiggler.h index d5336aae6..5ed667b23 100644 --- a/include/Wiggler.h +++ b/include/Wiggler.h @@ -1,19 +1,61 @@ -/* AUTO-GENERATED from matched-function evidence by tools/gen_header.py - * class Wiggler: 4 matched functions, 1 evidenced fields. - * Offsets/widths are observed, not guessed. Gaps are explicit padding. - * Field NAMES are placeholders - renaming cannot change codegen. */ #ifndef WIGGLER_H #define WIGGLER_H + #include "types.h" -struct Wiggler { - u8 pad_000[0x708]; - u8 mWithMeshClsn; /* 0x708 */ +/* The Wiggler. Five body segments, so five of everything -- and EIGHT arrays, + * which close on eight consecutive boundaries: + * + * Enemy ends 0x110 + * ModelAnim[5] 0x110 + 5*0x64 = 0x304 -> MaterialChanger + * MaterialChanger[5] 0x304 + 5*0x14 = 0x368 -> TextureSequence + * TextureSequence[5] 0x368 + 5*0x14 = 0x3cc -> the first triple + * Vector3[5] 0x3cc + 5*0x0c = 0x408 -> the second + * Vector3[5] 0x408 + 5*0x0c = 0x444 -> the shorts + * Vector3s[5] 0x444 + 5*0x06 = 0x462 + * MovingCylinderClsnWithPos[5] 0x478 + 5*0x40 = 0x5b8 -> the second set + * MovingCylinderClsnWithPos[5] 0x5b8 + 5*0x40 = 0x6f8 + * + * The Vector3s array is what named func_02011508 -- see the note on Vector3s in + * include/types.h and src/_ZN8Vector3sD1Ev.cpp. + */ + #ifdef __cplusplus - /* methods */ + +#include "Enemy.h" +#include "ModelAnim.h" +#include "MaterialChanger.h" +#include "TextureSequence.h" +#include "WithMeshClsn.h" +#include "MovingCylinderClsnWithPos.h" + +struct Wiggler : Enemy { + ModelAnim mModelAnims[5]; /* 0x110 */ + MaterialChanger mMaterialChangers[5]; /* 0x304 */ + TextureSequence mTextureSequences[5]; /* 0x368 */ + Vector3 unk_3cc[5]; /* 0x3cc */ + Vector3 unk_408[5]; /* 0x408 */ + Vector3s unk_444[5]; /* 0x444 */ + u8 pad_462[0x16]; + MovingCylinderClsnWithPos mCylinderClsns1[5]; /* 0x478 */ + MovingCylinderClsnWithPos mCylinderClsns2[5]; /* 0x5b8 */ + u8 pad_6f8[0x10]; + WithMeshClsn mWithMeshClsn; /* 0x708 */ + + virtual ~Wiggler(); + int InitResources(); int Render(); -#endif }; -#endif +#else + +/* The same object for a C translation unit, flat. */ +struct Wiggler { + u8 pad_000[0x708]; + u8 mWithMeshClsn[0x1bc]; /* 0x708 */ +}; + +#endif /* __cplusplus */ + +#endif /* WIGGLER_H */ diff --git a/include/types.h b/include/types.h index 1b7be8149..2506e351a 100644 --- a/include/types.h +++ b/include/types.h @@ -27,12 +27,43 @@ typedef s32 Fix12i; typedef struct Vector3 { Fix12i x, y, z; +#ifdef __cplusplus + /* DECLARED, AND EMPTY, BECAUSE THE ROM DESTROYS ARRAYS OF IT. A POD array + needs no cleanup, so ChiefChilly's + `__destroy_arr(this + 0x3e8, 8, 0xc, func_020072c0)` can only exist if + the element type declares a destructor -- and 0x020072c0 is four bytes, + `bx lr`, an empty one. config/arm9/symbols.txt names it + _ZN7Vector3D1Ev. + + This makes Vector3 non-POD everywhere, which is nearly free but not + quite: 10,812 of 10,813 enrolled functions are byte-identical either way, + and Rabbit::Behavior grows 8 bytes (0x5cc -> 0x5d4). That one is the + price of the six destructors this unblocks. */ + ~Vector3() {} +#endif } Vector3; +#ifdef __cplusplus +/* 0xc, and the ROM agrees twice over: ChiefChilly's arrays stride by 0xc and + its __destroy_arr calls pass 0xc as the element size. */ +typedef char Vector3_size_must_be_0xc[sizeof(Vector3) == 0xc ? 1 : -1]; +#endif + typedef struct Vector3s { s16 x, y, z; +#ifdef __cplusplus + /* Declared and empty, for the same reason Vector3's is: Wiggler destroys an + array of a 6-byte type through + __destroy_arr(this + 0x444, 5, 6, func_02011508), a POD array needs no + cleanup, and 0x02011508 is four bytes of `bx lr`. 6 is sizeof(Vector3s). */ + ~Vector3s() {} +#endif } Vector3s; +#ifdef __cplusplus +typedef char Vector3s_size_must_be_0x6[sizeof(Vector3s) == 6 ? 1 : -1]; +#endif + /* Floating-point aliases. */ typedef float f32; diff --git a/notes/handoff-class-skeleton.md b/notes/handoff-class-skeleton.md new file mode 100644 index 000000000..99971dbf2 --- /dev/null +++ b/notes/handoff-class-skeleton.md @@ -0,0 +1,202 @@ +# Handoff: the class skeleton, and how much of it is proven + +**Written 2026-08-07.** Branch `docs/class-reference-confidence`, five commits, pushed to +`origin`. Everything below is checkable; every number appears with the command that +produces it. Where an earlier answer was wrong, it is recorded rather than quietly fixed. + +--- + +## 0. Read this first if you are picking it up cold + +The question this answers is *"can this ROM be turned into matchable C++, or is that +impossible?"* The short version: + +**The interface is solved. The fields are not.** Those are different problems with +different oracles, and conflating them is the mistake this work exists to prevent. + +* **Fields are a weak oracle.** `notes/runbook-type-reconstruction.md` §2: a retype that + nothing reads emits identical bytes. 71 retypes across 119 TUs came out byte-identical + under `s32/s16` *and* `u32/u16`. The ROM cannot adjudicate most type questions. +* **The skeleton is a strong oracle.** Inheritance and virtual dispatch are not inferred + from code -- the compiler emits them as **data**, and that data is in the ROM. So a + C++ declaration can be compiled and byte-compared against retail. + +```sh +python tools/rtti_extract.py --report --check # -> build/rtti.json +python tools/rtti_vtables.py # -> build/rtti_vtables.json +python tools/rtti_reference.py # -> docs/class-reference.html +python tools/skeleton_conform.py --report # -> build/skeleton_conform.json +``` + +## 1. What is proven, with numbers + +`python tools/rtti_reference.py` prints these and writes the browsable page: + +| claim | count | of | | what makes it true | +|---|---:|---:|---|---| +| class exists and is named | 429 | 429 | 100% | the ROM stores the name string | +| base class known | 413 | 413 | 100% | a pointer in the typeinfo record | +| vtable located | 426 | 429 | 99.3% | bound to the record | +| slot resolves to a named function | 10984 | 11021 | 99.7% | slot → `config/**/symbols.txt` | +| …and that function has a source file | 10973 | 11021 | 99.6% | `tools/srcpath.py` | +| …and that file is **enrolled** | 10324 | 11021 | 93.7% | linked; rebuilt ROM byte-identical to retail | + +`python tools/skeleton_conform.py --report`: + +``` +checked 423: conform=420, bases_only=3 +skipped 6: no vtable slots (dBgPc, dM3dGLin, dMg3DHeyhoObjAdapter_c, daDemo_c::param_c) +``` + +**420 of 429 classes reproduce their vtable shape, offset-to-top, pure-virtual slots and +mangled name string from a compiled C++ declaration.** Zero mismatches. + +### What "conform" does and does not claim + +Compared **exactly**: the `_ZTS` name string, vtable offset-to-top, table length, which +slots are null, and for multiple inheritance the flags, base count and every base's +`offset_flags`. Those are literals. + +**Wildcarded**: every pointer word. In an object file it is an addend against an +undefined symbol; in the ROM it is a resolved address. `tools/match.py` has the identical +problem for code and solves it the same way. Whether the pointer words hold the *right* +functions is answered by a different join -- the 99.7%/93.7% rows above. + +Not claimed at all: field names, types, offsets, or method names. A named slot is not a +named method: where the symbol is a `func_*` placeholder the *position* is right and the +name is still unknown, and a vtable never carries a signature. + +## 2. The multiple-inheritance payload -- the ROM's only direct `sizeof` + +A `__vmi_class_type_info` record stores where each base **subobject** starts, as a +literal. Under Itanium a non-virtual base sits at the next available offset, so +consecutive starts state how much room the earlier base occupies. This is the one place +the ROM states layout outright. + +``` +dBgCh_SphCrr (SphereClsn) dBgCh@0 dBgPi@16 dM3dGSph@56 +dBgCh_Lin (RaycastLine) dBgCh@0 dBgPi@16 dM3dGLin@56 +dBgCh_Gnd dBgCh@0 dBgPi@16 +dExtAnmModel_c dExtSimpleModel_c@0 dExtFrameCtrl_c@80 +daDemo_c::anmModel_c dExtAnmModel_c@0 daDemo_c::param_c@100 +daDemo_c::simpleModel_c dExtSimpleModel_c@0 daDemo_c::param_c@80 + +implied: sizeof(dBgCh) 16 dBgPi 40 dExtSimpleModel_c 80 dExtAnmModel_c 100 +``` + +Each is corroborated by two or three independent records; none conflicts. + +**Two confirmations that were not inputs.** `include/BgCh.h`, hand-reconstructed from the +constructor's stores, says *"LAYOUT is 0x10 bytes"* -- 16, derived here from a different +structure entirely. And `include/SphereClsn.h`, a generated flat header, declares fields +starting at `0x010` and `0x038`; the record puts dBgPi at 16 and dM3dGSph at 56, and +16 + 40 = 56. **Both subobject boundaries land exactly on a field that generator already +found**, knowing nothing about any of this. + +> **If you are matching `DetectClsn(SphereClsn&)`:** everything below `0x38` in +> `include/SphereClsn.h` belongs to a base, not to SphereClsn. The ROM says that class +> has three bases; `include/` models one. See `notes/rtti-reconciliation.md` §4. + +**Honest about the circularity.** Taking offsets from the ROM and checking they come back +is close to vacuous. Two things make it not: the compiler gets a vote (declaration order, +alignment and the primary-base choice can each refuse), and the useful output is a +*restatement* -- "dBgPi starts at 16" becomes "sizeof(dBgCh) == 16", which is the form a +matcher can use. + +## 3. Two defects this found in `build/rtti_vtables.json` + +Both are fixed. Both were found by **using** the data rather than inspecting it, which is +the transferable part. + +**Over-read, 62 classes, 1128 slots.** The end-of-table rule only fired on a null whose +successor is a *known typeinfo record*. Where a `{0, handler}` table follows instead, the +successor is a code pointer, nothing fires, and the walk reads that table as slots. +`daPeach_c` ran to 62 slots against a real 31. + +The fix trims the longest strictly-alternating null/pointer suffix. Orientation is not the +signal -- `daPeach_c`'s tail reads `{fn, 0}` and `daObjSwdoor_c`'s reads `{0, fn}` -- the +*run* is. Both then land on their base's count exactly, which nobody put in by hand. + +**Under-read, 124 classes.** "Is this word code" was asked of the vtable's own module plus +arm9. Too narrow twice: ITCM is its own module and was never loaded (`dBgW_Kc` slots 3-7 +are `0x01ffd920`…), and a slot may point into a **different overlay** (`dScMgAmida_c`'s +table is in ov006 while slot 1 is ov004's code). Asking *every* module fails the other way +-- `dScStage_c` ran to 70 slots against a base of 18. The bound is residency +(`overlay_residency.conflict`, rule E2, the game's own `LoadOverlay` panic), applied +**one-directionally**: arm9 conflicts with nothing, so an arm9-hosted table gets no +cross-overlay allowance or the rule bounds nothing. + +**The invariant is now a gate.** A derived table is never shorter than its base's -- every +base slot is inherited or overridden and neither removes one. `rtti_vtables.py` fails the +run if it is violated. That invariant is what made both bugs findable. + +### The correction that followed + +`include/daObjSwdoor_c.h` declared four fields read from twelve "own" methods. Nine of the +twelve were the over-read tail. §8's attribution argument -- *a method can reach its own +members and its ancestors', never a descendant's* -- only licenses a field if the method +really is the class's, so **all four fields fell**: 3 own methods, 0 own fields. The header +is retracted, and `--emit-headers` now deletes a header it previously wrote for a class +with no remaining evidence. + +**The other four headers regenerate byte-identically** (4, 6, 4, 4 methods; same offsets, +same widths). A trim eating real data would have moved them too. That is the reason to +believe the fix and not merely the finding. + +## 4. What is still open, in the order I would take it + +1. **The 37 unnamed slots** are addresses hosted by two co-resident modules. The join + reports a genuine tie as unresolved rather than picking one. `tools/overlay_residency.py` + `settle()` may narrow some; the rest want a human. Low value, listed for completeness. +2. **`daDemo_c::anmModel_c` / `simpleModel_c`** report `bases_only`: they declare their + offset-100 / offset-80 base first and the primary second, which happens when the + first-declared base is not the one the compiler makes primary. A probe needs the + empty-base and primary-base rules modelled. Their offsets are already recorded. +3. **`dBgCh_Lin` needs `dM3dGLin`'s vtable.** It is one of three records with no vtable + bound (`dBgPc`, `dM3dGLin`, `daDemo_c::param_c`); `rtti_vtables.py` refuses to guess. + Settling any of them unblocks a probe and would confirm `dBgPi`'s size a third time. +4. **Surface conformance on `docs/class-reference.html`.** The data is in + `build/skeleton_conform.json` and the page does not read it yet. Cheap; it would let + the page state both "the code is byte-verified" and "the declaration is byte-verified". +5. **The real blocker for migration is unchanged and is not a codegen problem.** + `eligible.py` rejects any object with a `.data` section (85 files) and any with + multiple `.text` sections (13). A `~Class()` definition always emits D2/D0/D1, so + **enrolled destructor migrations in this tree: zero.** The prerequisite is a delink + model that can bind one source file to a multi-function address range. mwccarm emits + the group in D2, D0, D1 order, which is exactly the ROM's per-class layout -- one TU + already reproduces the contiguous range; nothing can bind it. See + `notes/dtor-variant-audit.md` §7. + +## 5. Wrong answers recorded, so they are not re-derived + +* **"9351 / 9351 slots named, 100.0%"** was an artifact, not an achievement. The walk + stopped early at precisely the slots it could not classify, so they were never in the + denominator. The corrected figure is 10984 / 11021 -- a lower percentage over 1670 more + slots. **A suspiciously perfect number is a reason to check the denominator.** +* **Trimming the over-read tail** was tried before refusing it, and the two orientations + disagree about which slot is last. Refusing was what dropped mismatches 43 → 0, which is + itself the evidence that the mismatches were bad slot data rather than a bad model. +* **`content-visibility: auto`** on the class page makes the browser guess card heights, + so a jump from the tree lands in blank space and the card never paints. Removed. The + weight it was there to fix is handled by building slot tables lazily (9351 rows as + markup is 2.8 MB and froze the renderer) and shipping groups collapsed (69,000px → 8,201px). +* **`skeleton_conform` reported "the probe emitted no `_ZTS`" for 57 classes** when the + probe was fine and its own ROM reader was the broken half -- a fixed 256-byte read + overran the end of the module. Always say *which side* of a comparison is missing. +* **Symbol lookups by prefix/suffix.** A probe object defines every ancestor's RTTI + symbols too, so a scan can return an ancestor's record and compare it against the leaf's + ROM bytes. Index by exact mangled name. + +## 6. Caveats on the artifacts + +`docs/class-reference.html` is generated and committed. It was generated from a working +tree on `d2/renames-small`, so its enrolled counts reflect that branch's `config/` and +`src/`, not `main`'s. Regenerate after merging; `--check` refuses to emit if its inputs +are stale, and warns if any slot resolves to no symbol. + +`build/*.json` are gitignored artifacts. `tools/skeleton_conform.py` needs +`tools/mwccarm/**` and `extracted/**`, neither of which a fresh clone has -- see +`notes/rom-build.md`. + +No `include/`, `config/` or `src/` file is touched by any of this except the retraction of +`include/daObjSwdoor_c.h`, which had zero consumers, so codegen cannot move. diff --git a/src/ChainChomp_Spawn.cpp b/src/ChainChomp_Spawn.cpp index 47d90f62f..f0a897dc8 100644 --- a/src/ChainChomp_Spawn.cpp +++ b/src/ChainChomp_Spawn.cpp @@ -10,7 +10,7 @@ extern int _ZTV10ChainChomp[]; extern void _ZN5ModelD1Ev(); extern void _ZN5ModelC1Ev(); extern void _ZN11ShadowModelD1Ev(); -extern void func_020072c0(); +extern void _ZN7Vector3D1Ev(); extern void func_0203d384(); void* ChainChomp_Spawn(void){ char* c = (char*)_ZN9ActorBasenwEj(0x620); @@ -22,8 +22,8 @@ void* ChainChomp_Spawn(void){ _ZN11ShadowModelC1Ev(c+0x1b4); func_020733a8(c+0x1dc, 7, 0x50, (void*)_ZN5ModelC1Ev, (void*)_ZN5ModelD1Ev); func_020733a8(c+0x40c, 7, 0x28, (void*)_ZN11ShadowModelC1Ev, (void*)_ZN11ShadowModelD1Ev); - func_020733a8(c+0x524, 7, 0xc, (void*)func_0203d384, (void*)func_020072c0); - func_020733a8(c+0x578, 7, 0xc, (void*)func_0203d384, (void*)func_020072c0); + func_020733a8(c+0x524, 7, 0xc, (void*)func_0203d384, (void*)_ZN7Vector3D1Ev); + func_020733a8(c+0x578, 7, 0xc, (void*)func_0203d384, (void*)_ZN7Vector3D1Ev); } return c; } diff --git a/src/ChiefChilly_Spawn.cpp b/src/ChiefChilly_Spawn.cpp index de6643c87..c4d816ac1 100644 --- a/src/ChiefChilly_Spawn.cpp +++ b/src/ChiefChilly_Spawn.cpp @@ -8,7 +8,7 @@ extern "C" void _ZN11ShadowModelC1Ev(void*); extern "C" void func_020733a8(void* p, int a, int b, void* f1, void* f2); extern int _ZTV11ChiefChilly; -extern "C" void func_020072c0(void); +extern "C" void _ZN7Vector3D1Ev(void); extern "C" void func_0203d384(void); extern "C" void* ChiefChilly_Spawn(void) @@ -21,9 +21,9 @@ extern "C" void* ChiefChilly_Spawn(void) _ZN12WithMeshClsnC1Ev(p + 0x150); _ZN14BlendModelAnimC1Ev(p + 0x30c); _ZN11ShadowModelC1Ev(p + 0x380); - func_020733a8(p + 0x3e8, 8, 0xc, (void*)&func_0203d384, (void*)&func_020072c0); - func_020733a8(p + 0x448, 8, 0xc, (void*)&func_0203d384, (void*)&func_020072c0); - func_020733a8(p + 0x4d4, 2, 0xc, (void*)&func_0203d384, (void*)&func_020072c0); + func_020733a8(p + 0x3e8, 8, 0xc, (void*)&func_0203d384, (void*)&_ZN7Vector3D1Ev); + func_020733a8(p + 0x448, 8, 0xc, (void*)&func_0203d384, (void*)&_ZN7Vector3D1Ev); + func_020733a8(p + 0x4d4, 2, 0xc, (void*)&func_0203d384, (void*)&_ZN7Vector3D1Ev); } return p; } diff --git a/src/ExplosionGoomba_Spawn.cpp b/src/ExplosionGoomba_Spawn.cpp index 9d4330485..758df442a 100644 --- a/src/ExplosionGoomba_Spawn.cpp +++ b/src/ExplosionGoomba_Spawn.cpp @@ -12,7 +12,7 @@ extern void _ZN25MovingCylinderClsnWithPosD1Ev(void*); extern void _ZN25MovingCylinderClsnWithPosC1Ev(void*); extern void _ZN11ShadowModelD1Ev(void*); extern void _ZN11ShadowModelC1Ev(void*); -extern void func_020072c0(void*); +extern void _ZN7Vector3D1Ev(void*); extern void func_0203d384(void*); extern void* _ZTV8Goomboss[]; void* ExplosionGoomba_Spawn(void){ @@ -23,7 +23,7 @@ void* ExplosionGoomba_Spawn(void){ func_020733a8(p+0x110, 4, 0x40, _ZN25MovingCylinderClsnWithPosC1Ev, _ZN25MovingCylinderClsnWithPosD1Ev); _ZN9ModelAnimC1Ev(p+0x210); func_020733a8(p+0x274, 3, 0x28, _ZN11ShadowModelC1Ev, _ZN11ShadowModelD1Ev); - func_020733a8(p+0x3ac, 3, 0xc, func_0203d384, func_020072c0); + func_020733a8(p+0x3ac, 3, 0xc, func_0203d384, _ZN7Vector3D1Ev); _ZN15MaterialChangerC1Ev(p+0x3d0); _ZN15TextureSequenceC1Ev(p+0x3e4); _ZN18TextureTransformerC1Ev(p+0x3f8); diff --git a/src/Eyerok_Spawn.cpp b/src/Eyerok_Spawn.cpp index d5e431924..c02951fa2 100644 --- a/src/Eyerok_Spawn.cpp +++ b/src/Eyerok_Spawn.cpp @@ -8,7 +8,7 @@ extern "C" void _ZN11ShadowModelC1Ev(void *thiz); extern "C" void _ZN15TextureSequenceC1Ev(void *thiz); extern "C" void func_020733a8(void *p, int a, int b, void *f1, void *f2); extern "C" void _ZN18MovingMeshColliderC1Ev(void *thiz); -extern "C" void func_020072c0(void); +extern "C" void _ZN7Vector3D1Ev(void); extern "C" void func_0203d384(void); extern void *_ZTV6Eyerok[]; @@ -23,7 +23,7 @@ extern "C" void *Eyerok_Spawn(void) _ZN5ModelC1Ev(c + 0x3d0); _ZN11ShadowModelC1Ev(c + 0x420); _ZN15TextureSequenceC1Ev(c + 0x448); - func_020733a8(c + 0x4dc, 0x14, 0xc, (void *)func_0203d384, (void *)func_020072c0); + func_020733a8(c + 0x4dc, 0x14, 0xc, (void *)func_0203d384, (void *)_ZN7Vector3D1Ev); _ZN18MovingMeshColliderC1Ev(c + 0x674); } return c; diff --git a/src/Flamethrower_Spawn.cpp b/src/Flamethrower_Spawn.cpp index fd2cc7da6..0cf98dd02 100644 --- a/src/Flamethrower_Spawn.cpp +++ b/src/Flamethrower_Spawn.cpp @@ -4,7 +4,7 @@ extern void* _ZN9ActorBasenwEj(unsigned int); extern void _ZN5ActorC2Ev(void*); extern void _ZN19CylinderClsnWithPosD1Ev(void*); extern void _ZN19CylinderClsnWithPosC1Ev(void*); -extern void func_020072c0(void*); +extern void _ZN7Vector3D1Ev(void*); extern void func_0203d384(void*); extern void func_020733a8(void* arr, int count, int size, void(*ctor)(void*), void(*dtor)(void*)); extern void* _ZTV12Flamethrower[]; @@ -15,7 +15,7 @@ int* Flamethrower_Spawn(void){ _ZN5ActorC2Ev(p); *(void***)p = (void**)_ZTV12Flamethrower; func_020733a8((char*)p+0xd4, 0xc, 0x3c, _ZN19CylinderClsnWithPosC1Ev, _ZN19CylinderClsnWithPosD1Ev); - func_020733a8((char*)p+0x3a4, 0xc, 0xc, func_0203d384, func_020072c0); + func_020733a8((char*)p+0x3a4, 0xc, 0xc, func_0203d384, _ZN7Vector3D1Ev); } return p; } diff --git a/src/Goomboss_Spawn.cpp b/src/Goomboss_Spawn.cpp index 8900e632a..10df2891c 100644 --- a/src/Goomboss_Spawn.cpp +++ b/src/Goomboss_Spawn.cpp @@ -12,7 +12,7 @@ extern void _ZN25MovingCylinderClsnWithPosD1Ev(void*); extern void _ZN25MovingCylinderClsnWithPosC1Ev(void*); extern void _ZN11ShadowModelD1Ev(void*); extern void _ZN11ShadowModelC1Ev(void*); -extern void func_020072c0(void*); +extern void _ZN7Vector3D1Ev(void*); extern void func_0203d384(void*); extern void* _ZTV8Goomboss[]; void* Goomboss_Spawn(void){ @@ -23,7 +23,7 @@ void* Goomboss_Spawn(void){ func_020733a8(p+0x110, 4, 0x40, _ZN25MovingCylinderClsnWithPosC1Ev, _ZN25MovingCylinderClsnWithPosD1Ev); _ZN9ModelAnimC1Ev(p+0x210); func_020733a8(p+0x274, 3, 0x28, _ZN11ShadowModelC1Ev, _ZN11ShadowModelD1Ev); - func_020733a8(p+0x3ac, 3, 0xc, func_0203d384, func_020072c0); + func_020733a8(p+0x3ac, 3, 0xc, func_0203d384, _ZN7Vector3D1Ev); _ZN15MaterialChangerC1Ev(p+0x3d0); _ZN15TextureSequenceC1Ev(p+0x3e4); _ZN18TextureTransformerC1Ev(p+0x3f8); diff --git a/src/PyramidLift_Spawn.cpp b/src/PyramidLift_Spawn.cpp index f634fd254..878679de0 100644 --- a/src/PyramidLift_Spawn.cpp +++ b/src/PyramidLift_Spawn.cpp @@ -5,7 +5,7 @@ extern void _ZN8PlatformC2Ev(void*); extern void _ZN5ModelC1Ev(void*); extern int func_020733a8(void*,int,int,void*,void*); extern void* _ZTV11PyramidLift; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void func_0203d384(void); void* PyramidLift_Spawn(void){ char* c=(char*)_ZN9ActorBasenwEj(0x3fc); @@ -13,7 +13,7 @@ void* PyramidLift_Spawn(void){ _ZN8PlatformC2Ev(c); *(void**)c=&_ZTV11PyramidLift; _ZN5ModelC1Ev(c+0x320); - func_020733a8(c+0x37c, 0xa, 0xc, (void*)func_0203d384, (void*)func_020072c0); + func_020733a8(c+0x37c, 0xa, 0xc, (void*)func_0203d384, (void*)_ZN7Vector3D1Ev); } return c; } diff --git a/src/Unagi_Spawn.c b/src/Unagi_Spawn.c index a39acca2a..3c1059f04 100644 --- a/src/Unagi_Spawn.c +++ b/src/Unagi_Spawn.c @@ -5,7 +5,7 @@ extern void _ZN12WithMeshClsnC1Ev(void *); extern void _ZN14BlendModelAnimC1Ev(void *); extern void func_020733a8(void*, int, int, void*, void*); extern int _ZTV5Unagi[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int func_0203d384[]; int *Unagi_Spawn(void) { @@ -17,7 +17,7 @@ int *Unagi_Spawn(void) _ZN25MovingCylinderClsnWithPosC1Ev((char *)p + 0x150); _ZN12WithMeshClsnC1Ev((char *)p + 0x190); _ZN14BlendModelAnimC1Ev((char *)p + 0x350); - func_020733a8((char *)p + 0x448, 7, 0xc, (void*)func_0203d384, (void*)func_020072c0); + func_020733a8((char *)p + 0x448, 7, 0xc, (void*)func_0203d384, (void*)_ZN7Vector3D1Ev); } return p; } diff --git a/src/UnchainedChomp_Spawn.c b/src/UnchainedChomp_Spawn.c index 34b7edbc2..62e69896f 100644 --- a/src/UnchainedChomp_Spawn.c +++ b/src/UnchainedChomp_Spawn.c @@ -9,9 +9,9 @@ extern int _ZTV14UnchainedChomp; extern void _ZN5ModelC1Ev(void); extern void _ZN5ModelD1Ev(void); extern void _ZN11ShadowModelD1Ev(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void func_0203d384(void); -extern void func_02011508(void); +extern void _ZN8Vector3sD1Ev(void); extern void func_0203d73c(void); void *UnchainedChomp_Spawn(void) @@ -26,9 +26,9 @@ void *UnchainedChomp_Spawn(void) func_020733a8(p + 0x370, 6, 0x50, (void *)_ZN5ModelC1Ev, (void *)_ZN5ModelD1Ev); func_020733a8(p + 0x550, 6, 0x28, (void *)_ZN11ShadowModelC1Ev, (void *)_ZN11ShadowModelD1Ev); _ZN11ShadowModelC1Ev(p + 0x640); - func_020733a8(p + 0x6d8, 6, 0xc, (void *)func_0203d384, (void *)func_020072c0); - func_020733a8(p + 0x720, 6, 0xc, (void *)func_0203d384, (void *)func_020072c0); - func_020733a8(p + 0x768, 6, 6, (void *)func_0203d73c, (void *)func_02011508); + func_020733a8(p + 0x6d8, 6, 0xc, (void *)func_0203d384, (void *)_ZN7Vector3D1Ev); + func_020733a8(p + 0x720, 6, 0xc, (void *)func_0203d384, (void *)_ZN7Vector3D1Ev); + func_020733a8(p + 0x768, 6, 6, (void *)func_0203d73c, (void *)_ZN8Vector3sD1Ev); } return p; } diff --git a/src/Wiggler_Spawn.c b/src/Wiggler_Spawn.c index 61c9116c8..98730f14f 100644 --- a/src/Wiggler_Spawn.c +++ b/src/Wiggler_Spawn.c @@ -5,9 +5,9 @@ extern int _ZN12WithMeshClsnC1Ev(void *p); extern int _ZN25MovingCylinderClsnWithPosC1Ev(void *p); extern int _ZN25MovingCylinderClsnWithPosD1Ev(void *p); extern int func_0203d73c(void *p); -extern int func_02011508(void *p); +extern int _ZN8Vector3sD1Ev(void *p); extern int func_0203d384(void *p); -extern int func_020072c0(void *p); +extern int _ZN7Vector3D1Ev(void *p); extern int _ZN15TextureSequenceC1Ev(void *p); extern int _ZN15TextureSequenceD1Ev(void *p); extern int _ZN15MaterialChangerC1Ev(void *p); @@ -24,9 +24,9 @@ void *Wiggler_Spawn(void){ func_020733a8(c+0x110, 5, 0x64, _ZN9ModelAnimC1Ev, _ZN9ModelAnimD1Ev); func_020733a8(c+0x304, 5, 0x14, _ZN15MaterialChangerC1Ev, _ZN15MaterialChangerD1Ev); func_020733a8(c+0x368, 5, 0x14, _ZN15TextureSequenceC1Ev, _ZN15TextureSequenceD1Ev); - func_020733a8(c+0x3cc, 5, 0xc, func_0203d384, func_020072c0); - func_020733a8(c+0x408, 5, 0xc, func_0203d384, func_020072c0); - func_020733a8(c+0x444, 5, 6, func_0203d73c, func_02011508); + func_020733a8(c+0x3cc, 5, 0xc, func_0203d384, _ZN7Vector3D1Ev); + func_020733a8(c+0x408, 5, 0xc, func_0203d384, _ZN7Vector3D1Ev); + func_020733a8(c+0x444, 5, 6, func_0203d73c, _ZN8Vector3sD1Ev); func_020733a8(c+0x478, 5, 0x40, _ZN25MovingCylinderClsnWithPosC1Ev, _ZN25MovingCylinderClsnWithPosD1Ev); func_020733a8(c+0x5b8, 5, 0x40, _ZN25MovingCylinderClsnWithPosC1Ev, _ZN25MovingCylinderClsnWithPosD1Ev); _ZN12WithMeshClsnC1Ev(c+0x708); diff --git a/src/_ZN10BowserFire13InitResourcesEv.cpp b/src/_ZN10BowserFire13InitResourcesEv.cpp index 721e126a5..8ca795026 100644 --- a/src/_ZN10BowserFire13InitResourcesEv.cpp +++ b/src/_ZN10BowserFire13InitResourcesEv.cpp @@ -63,16 +63,16 @@ int BowserFire::InitResources() _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_( &this->mWithMeshClsn, this, 0x32000, 0x32000, 0, 0); - this->unk_09c = -0x4000; - this->unk_0a0 = -0x1e000; - this->unk_35c = this->mParam & 7; + this->mVertAccel = -0x4000; + this->mTerminalVelocity = -0x1e000; + this->unk_35c = this->param1 & 7; this->unk_374 = 0; if (this->unk_35c == 0) this->unk_379 = 0; else this->unk_379 = 1; this->unk_36c = 0; - this->unk_378 = ((unsigned int)this->mParam >> 4) & 3; + this->unk_378 = ((unsigned int)this->param1 >> 4) & 3; if (this->unk_35c == 0) this->mMovingCylinderClsn.flags |= 1; this->unk_360 = 0x2000; diff --git a/src/_ZN10BowserFire8BehaviorEv.cpp b/src/_ZN10BowserFire8BehaviorEv.cpp index 0cb65ff00..77aa727cb 100644 --- a/src/_ZN10BowserFire8BehaviorEv.cpp +++ b/src/_ZN10BowserFire8BehaviorEv.cpp @@ -17,12 +17,12 @@ int BowserFire::Behavior() *(int*)(((int)((char *)this) + 0x370)) += 1; (self->*data_ov060_0211afb4[unk_35c].pmf)(); *(unsigned short*)(((int)((char *)this) + 0x374)) += 1; - if (unk_09c != 0) { + if (mVertAccel != 0) { WithMeshClsn_UpdateDiscreteNoLava_veneer((char *)&mWithMeshClsn); if (unk_35c != 4) { if (_ZNK12WithMeshClsn10IsOnGroundEv((char *)&mWithMeshClsn) != 0) { mVertSpeed = 0; - unk_09c = 0; + mVertAccel = 0; } } } diff --git a/src/_ZN10BulletBill8BehaviorEv.cpp b/src/_ZN10BulletBill8BehaviorEv.cpp index 1c104f387..3ee481fb2 100644 --- a/src/_ZN10BulletBill8BehaviorEv.cpp +++ b/src/_ZN10BulletBill8BehaviorEv.cpp @@ -5,7 +5,7 @@ * One frame of the bullet: move, run the current state's tick out of the pmf * table, then resolve whatever the cylinder hit. * - * unk_134 is the ID of whatever it collided with, and unk_130 the flags of that + * (*(u32 *)((char *)&mMovingCylinderClsnWithPos + 0x24)) is the ID of whatever it collided with, and (*(s32 *)((char *)&mMovingCylinderClsnWithPos + 0x20)) the flags of that * hit -- three outcomes in priority order: * 0x10 hit by a mega character: the bullet dies, credits the kill, and * spawns particle 0x8f at its own position @@ -68,9 +68,9 @@ int BulletBill::Behavior() (((Klass *)c)->*(m->pmf))(); } - id = unk_134; + id = (*(u32 *)((char *)&mMovingCylinderClsnWithPos + 0x24)); if (id != 0) { - flags = unk_130; + flags = (*(s32 *)((char *)&mMovingCylinderClsnWithPos + 0x20)); if (flags & 0x10) { _ZN5Actor10FindWithIDEj(id); _ZN6Player16IncMegaKillCountEv(); diff --git a/src/_ZN10ChainChompD0Ev.cpp b/src/_ZN10ChainChompD0Ev.cpp index 87220340c..6fad793f3 100644 --- a/src/_ZN10ChainChompD0Ev.cpp +++ b/src/_ZN10ChainChompD0Ev.cpp @@ -1,32 +1,14 @@ //cpp // @symbol _ZN10ChainChompD0Ev -/* recovered: named members + shared header, declarations from a shared header */ -#include "decl_Model.h" -#include "decl_ModelAnim.h" -#include "decl_ShadowModel.h" -#include "decl_common.h" -/* recovered: named members + shared header, vtable identified */ -/* resolved: VT0 = _ZTV10ChainChomp */ +/* recovered: real C++ deleting destructor -- the compiler emits the whole body + * + * Destroy through ChainChomp and Enemy, then hand the object back through + * Actor's inline operator delete. The hand-written version declared its own + * `data_020a0eac` for the actor heap, which collides with the `void *` Actor.h + * supplies for that same symbol once the real header is in scope. + */ #include "ChainChomp.h" -extern "C" { -extern int __destroy_arr(void *p, int a, int b, void *fn); -extern void _ZN25MovingCylinderClsnWithPosD1Ev(void *p); -extern int _ZN5EnemyD2Ev(int *x); -extern int _ZTV10ChainChomp[]; -extern int func_020072c0(void); -extern int data_020a0eac; -void *_ZN10ChainChompD0Ev(struct ChainChomp *self) { - *(int**)((char *)self) = _ZTV10ChainChomp; - __destroy_arr(((char *)self) + 0x578, 7, 0xc, (void*)func_020072c0); - __destroy_arr(((char *)self) + 0x524, 7, 0xc, (void*)func_020072c0); - __destroy_arr(((char *)self) + 0x40c, 7, 0x28, (void*)_ZN11ShadowModelD1Ev); - __destroy_arr(((char *)self) + 0x1dc, 7, 0x50, (void*)_ZN5ModelD1Ev); - _ZN11ShadowModelD1Ev((char *)&self->mShadowModel); - _ZN9ModelAnimD1Ev((char *)&self->mModelAnim); - _ZN25MovingCylinderClsnWithPosD1Ev((char *)&self->mMovingCylinderClsnWithPos); - _ZN5EnemyD2Ev((int*)((char *)self)); - _ZN6Memory10DeallocateEPvP4Heap(((char *)self), *(void**)&data_020a0eac); - return ((char *)self); -} +ChainChomp::~ChainChomp() +{ } diff --git a/src/_ZN10ChainChompD1Ev.c b/src/_ZN10ChainChompD1Ev.c deleted file mode 100644 index 11586512f..000000000 --- a/src/_ZN10ChainChompD1Ev.c +++ /dev/null @@ -1,26 +0,0 @@ -// @symbol _ZN10ChainChompD1Ev -/* recovered: named members + shared header, declarations from a shared header */ -#include "decl_Model.h" -#include "decl_ModelAnim.h" -#include "decl_ShadowModel.h" -/* recovered: named members + shared header, vtable identified */ -/* resolved: VT0 = _ZTV10ChainChomp */ -#include "ChainChomp.h" -extern int __destroy_arr(void *arr, int n, int sz, void *dtor); -extern void func_020072c0(void); -extern void _ZN25MovingCylinderClsnWithPosD1Ev(void *p); -extern int _ZN5EnemyD2Ev(int *x); -extern int _ZTV10ChainChomp[]; - -void *_ZN10ChainChompD1Ev(struct ChainChomp *self) { - *(int**)((char *)self) = _ZTV10ChainChomp; - __destroy_arr(((char *)self) + 0x578, 7, 0xc, (void*)func_020072c0); - __destroy_arr(((char *)self) + 0x524, 7, 0xc, (void*)func_020072c0); - __destroy_arr(((char *)self) + 0x40c, 7, 0x28, (void*)_ZN11ShadowModelD1Ev); - __destroy_arr(((char *)self) + 0x1dc, 7, 0x50, (void*)_ZN5ModelD1Ev); - _ZN11ShadowModelD1Ev((char *)&self->mShadowModel); - _ZN9ModelAnimD1Ev((char *)&self->mModelAnim); - _ZN25MovingCylinderClsnWithPosD1Ev((char *)&self->mMovingCylinderClsnWithPos); - _ZN5EnemyD2Ev((int*)((char *)self)); - return ((char *)self); -} diff --git a/src/_ZN10ChainChompD1Ev.cpp b/src/_ZN10ChainChompD1Ev.cpp new file mode 100644 index 000000000..78bb013b8 --- /dev/null +++ b/src/_ZN10ChainChompD1Ev.cpp @@ -0,0 +1,14 @@ +//cpp +// @symbol _ZN10ChainChompD1Ev +/* recovered: real C++ destructor -- the compiler emits the whole body + * + * Four array cleanups and three member destructors, reverse declaration order + * out of ChainChomp.h. Seven links means seven of nearly everything: Model[7] + * at 0x1dc, ShadowModel[7] at 0x40c, and two Vector3[7] at 0x524 and 0x578 for + * the per-link positions. Every element type was already named in the tree. + */ +#include "ChainChomp.h" + +ChainChomp::~ChainChomp() +{ +} diff --git a/src/_ZN10CheepCheep13InitResourcesEv.cpp b/src/_ZN10CheepCheep13InitResourcesEv.cpp index 4330111a9..530246ffa 100644 --- a/src/_ZN10CheepCheep13InitResourcesEv.cpp +++ b/src/_ZN10CheepCheep13InitResourcesEv.cpp @@ -34,23 +34,23 @@ int CheepCheep::InitResources() struct Vector3 v; bmd = _ZN5Model8LoadFileER13SharedFilePtr(data_ov090_02134564); - _ZN9ModelBase7SetFileEP8BMD_Fileii((void *)((char *)&mModelAnim), bmd, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii((void *)((char *)&(*(u8 *)&mModelAnim)), bmd, 1, -1); _ZN9Animation8LoadFileER13SharedFilePtr(*(struct SharedFilePtr *)&data_ov090_0213455c); v = data_ov090_021342d8; _ZN25MovingCylinderClsnWithPos4InitEP5ActorRK7Vector35Fix12IiES6_jj( - (void *)((char *)&mMovingCylinderClsnWithPos), (struct Actor *)((char *)this), v, 0x32000, 0x3c000, 0x200004, 0x8000); + (void *)((char *)&(*(MovingCylinderClsnWithPos *)&mMovingCylinderClsnWithPos)), (struct Actor *)((char *)this), v, 0x32000, 0x3c000, 0x200004, 0x8000); unk_374 = mPosX; unk_378 = mPosY; unk_37c = mPosZ; mAngleY = mPrevAngleY; _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_( - (void *)((char *)&mWithMeshClsn), (struct Actor *)((char *)this), 0x1e000, 0x1e000, 0, 0); + (void *)((char *)&(*(WithMeshClsn *)&mWithMeshClsn)), (struct Actor *)((char *)this), 0x1e000, 0x1e000, 0, 0); _ZN9ModelAnim7SetAnimEP8BCA_Filei5Fix12IiEj( - (void *)((char *)&mModelAnim), data_ov090_0213455c.file, 0, 0x1000, 0); + (void *)((char *)&(*(u8 *)&mModelAnim)), data_ov090_0213455c.file, 0, 0x1000, 0); func_ov090_021332e8(((char *)this), &data_ov090_02134594); return 1; diff --git a/src/_ZN10CheepCheep6RenderEv.cpp b/src/_ZN10CheepCheep6RenderEv.cpp index 8955c1789..08be78e4b 100644 --- a/src/_ZN10CheepCheep6RenderEv.cpp +++ b/src/_ZN10CheepCheep6RenderEv.cpp @@ -13,9 +13,9 @@ struct Obj { int CheepCheep::Render() { - int b = ((unk_0b0 & 0x40000) != 0); + int b = ((mFlags & 0x40000) != 0); if (b) return 1; - Obj *o = (Obj*)((char *)&mModelAnim); + Obj *o = (Obj*)((char *)&(*(u8 *)&mModelAnim)); o->Target(0); return 1; } diff --git a/src/_ZN10CheepCheep8BehaviorEv.cpp b/src/_ZN10CheepCheep8BehaviorEv.cpp index 9a6a9225f..0e16564a3 100644 --- a/src/_ZN10CheepCheep8BehaviorEv.cpp +++ b/src/_ZN10CheepCheep8BehaviorEv.cpp @@ -21,7 +21,6 @@ extern void _ZN9Animation7AdvanceEv(void *thiz); extern char *_ZN5Actor13ClosestPlayerEv(Enemy *thiz); } -struct Enemy { char pad[0x800]; }; int CheepCheep::Behavior() { diff --git a/src/_ZN10DonutBlock13InitResourcesEv.cpp b/src/_ZN10DonutBlock13InitResourcesEv.cpp index 1203051b4..d24751fb3 100644 --- a/src/_ZN10DonutBlock13InitResourcesEv.cpp +++ b/src/_ZN10DonutBlock13InitResourcesEv.cpp @@ -1,55 +1,33 @@ //cpp // @symbol _ZN10DonutBlock13InitResourcesEv -/* recovered: named members + shared header, real C++ method - * - * Load the model and the collision mesh out of this overlay's file table, put - * both where the actor is, and pick the spin rate. - * - * The three raw offsets are gone: `this + 0xd4` is Platform::mModel, - * `this + 0x124` is Platform::mMeshCollider, and the `this + 0x2ec` handed to - * SetFile as its matrix is Platform::mClsnMat -- which UpdateClsnPosAndRot - * filled in on the line above. A local `typedef int Fix12` went with them; the - * real Fix12 is a template. - * - * unk_31e is the per-frame yaw step. It defaults to -0x80 and takes mAngleZ - * instead when the level author set one, so the field is reused as a - * placement parameter at load time. - * - * The calls keep their mangled spellings: SetFile's name carries Fix12 by - * value (wall 6az), and func_020393d4 and the callback it is handed are still - * unnamed. - */ +/* recovered: named members + shared header, real C++ method */ #include "DonutBlock.h" - extern "C" { -extern void *_ZN5Model8LoadFileER13SharedFilePtr(void *ptr); -extern int _ZN9ModelBase7SetFileEP8BMD_Fileii(void *self, void *file, int a, int b); -extern int _ZN8Platform21UpdateModelPosAndRotYEv(void *self); -extern int _ZN8Platform19UpdateClsnPosAndRotEv(void *self); -extern void *_ZN12MeshCollider8LoadFileER13SharedFilePtr(void *ptr); -extern int _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - void *self, void *file, void *mat, int scale, short angY, void *clps); -extern int func_020393d4(void *self, void *callback); +extern void* _ZN5Model8LoadFileER13SharedFilePtr(void*); +extern int _ZN9ModelBase7SetFileEP8BMD_Fileii(void*, void*, int, int); +extern int _ZN8Platform21UpdateModelPosAndRotYEv(void*); +extern int _ZN8Platform19UpdateClsnPosAndRotEv(void*); +extern void* _ZN12MeshCollider8LoadFileER13SharedFilePtr(void*); +extern int _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(void*, void*, void*, int, short, void*); +extern int func_020393d4(void*, void*); +} +extern void* data_ov036_02113d78[]; +extern "C" { extern int _ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_(void); } -extern void *data_ov036_02113d78[]; - int DonutBlock::InitResources() { - void *mdl = _ZN5Model8LoadFileER13SharedFilePtr(data_ov036_02113d78[0]); - _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, mdl, 1, -1); - _ZN8Platform21UpdateModelPosAndRotYEv(this); - _ZN8Platform19UpdateClsnPosAndRotEv(this); - - void *kcl = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov036_02113d78[1]); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - &mMeshCollider, kcl, &mClsnMat, 0x1000, mAngleY, data_ov036_02113d78[2]); - func_020393d4(&mMeshCollider, - &_ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); - - unk_31e = -0x80; - if (mAngleZ != 0) - unk_31e = mAngleZ; - return 1; + void* mdl; + void* kcl; + mdl = _ZN5Model8LoadFileER13SharedFilePtr(data_ov036_02113d78[0]); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, mdl, 1, -1); + _ZN8Platform21UpdateModelPosAndRotYEv(this); + _ZN8Platform19UpdateClsnPosAndRotEv(this); + kcl = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov036_02113d78[1]); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(&mMeshCollider, kcl, &mClsnMat, 0x1000, mAngleY, data_ov036_02113d78[2]); + func_020393d4(&mMeshCollider, &_ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + unk_31e = -0x80; + if (mAngleZ != 0) unk_31e = mAngleZ; + return 1; } diff --git a/src/_ZN10DonutBlock8BehaviorEv.cpp b/src/_ZN10DonutBlock8BehaviorEv.cpp index 0edbcf844..af305c15b 100644 --- a/src/_ZN10DonutBlock8BehaviorEv.cpp +++ b/src/_ZN10DonutBlock8BehaviorEv.cpp @@ -7,9 +7,9 @@ * matter, the collision mesh too. * * Three shadow declarations are gone -- a `typedef int Fix12` and stand-in - * `MeshColliderBase` and `Platform` structs -- with the raw offsets they + * `MeshColliderBase` and `Platform` structs -- along with the raw offsets they * served. `this + 0x8e` is Actor::mAngleY, and the `t[0x1e/2]` read off - * `this + 0x300` is this class's own unk_31e reached the long way round. + * `this + 0x300` was this class's own unk_31e reached the long way round. * * IsClsnInRange keeps its mangled spelling: the name carries Fix12 by * value, wall 6az, so a real call would not reproduce the call site. @@ -22,7 +22,7 @@ int DonutBlock::Behavior() { /* `+=`, not `mAngleY = mAngleY + ...`: the compound form CSEs the field address into a register and reuses it for the load and the store, which - is what the ROM does here. That is a per-SITE fact -- the opposite + is what the ROM does here. That is a per-SITE fact -- the expanded spelling is the matching one in Player::St_WallJump_Init. */ mAngleY += unk_31e; diff --git a/src/_ZN10DonutBlockD1Ev.cpp b/src/_ZN10DonutBlockD1Ev.cpp index e1ebdef00..f630cd574 100644 --- a/src/_ZN10DonutBlockD1Ev.cpp +++ b/src/_ZN10DonutBlockD1Ev.cpp @@ -5,8 +5,8 @@ * Two vtable stores and three destructor calls, every one a consequence of * `struct DonutBlock : Platform`: its own vptr, then Platform's -- inlined, * because Platform's destructor is defined in its class body -- then - * Platform's Model and MovingMeshCollider, then Actor. This class adds no - * member with a destructor. + * Platform's Model and MovingMeshCollider, then Actor. DonutBlock adds one + * s16, which has no destructor. */ #include "DonutBlock.h" diff --git a/src/_ZN10KingBobOmb13InitResourcesEv.cpp b/src/_ZN10KingBobOmb13InitResourcesEv.cpp index 159d77a66..759d7855d 100644 --- a/src/_ZN10KingBobOmb13InitResourcesEv.cpp +++ b/src/_ZN10KingBobOmb13InitResourcesEv.cpp @@ -46,7 +46,7 @@ int KingBobOmb::InitResources() int i; f = _ZN5Model8LoadFileER13SharedFilePtr(&data_ov078_02126f38); _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this)+0x2cc, f, 1, 1); - _ZN11ShadowModel12InitCylinderEv((char*)&mShadowModel); + _ZN11ShadowModel12InitCylinderEv((char*)&(*(u8 *)&mShadowModel)); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov078_02126f00); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov078_02126f20); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov078_02126f10); @@ -59,8 +59,8 @@ int KingBobOmb::InitResources() _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov078_02126ee8); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov078_02126f28); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov078_02126ef8); - unk_09c = -0x2000; - unk_0a0 = -0x3c000; + mVertAccel = -0x2000; + mTerminalVelocity = -0x3c000; v0.x = data_ov078_02126e00.x; v0.y = data_ov078_02126e00.y; v0.z = data_ov078_02126e00.z; @@ -77,10 +77,10 @@ int KingBobOmb::InitResources() unk_4d8 = 0x1060000; unk_4dc = 0xfee15000; _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_(((char*)this)+0x110, (Actor*)((char*)this), 0x190000, 0x190000, 0, 0); - func_02035550((char*)&mWithMeshClsn); + func_02035550((char*)&(*(WithMeshClsn *)&mWithMeshClsn)); unk_4fc = 1; unk_500 = 3; - unk_509 = mParam & 0xf; + unk_509 = (*(s32 *)¶m1) & 0xf; unk_507 = _ZN5Actor9TrackStarEjj(((char*)this), unk_509, 2); #pragma opt_strength_reduction off { diff --git a/src/_ZN10KingBobOmb6RenderEv.cpp b/src/_ZN10KingBobOmb6RenderEv.cpp index 550c5cedb..f22f65d41 100644 --- a/src/_ZN10KingBobOmb6RenderEv.cpp +++ b/src/_ZN10KingBobOmb6RenderEv.cpp @@ -12,7 +12,7 @@ int KingBobOmb::Render() { void *r1 = (void*)*(int*)((char*)&unk_494); if (r1 != 0) { - int r0 = *(int*)((char*)&unk_0b0); + int r0 = *(int*)((char*)&mFlags); int flag = (r0 & 0x4000) ? 1 : 0; if (flag != 0) { if (*(int*)((char*)r1 + 0xc8) != 0) { diff --git a/src/_ZN10KoopaShell13InitResourcesEv.cpp b/src/_ZN10KoopaShell13InitResourcesEv.cpp index 06743d428..d59d1c67b 100644 --- a/src/_ZN10KoopaShell13InitResourcesEv.cpp +++ b/src/_ZN10KoopaShell13InitResourcesEv.cpp @@ -5,7 +5,7 @@ * Builds the shell: model, shadow, both collision volumes, initial motion, and * the starting state. Any failure returns 0 and the spawn is abandoned. * - * One spawn word does double duty. mSpawnParam bit 0 picks which of the two + * One spawn word does double duty. param1 bit 0 picks which of the two * shared model files to load and is kept in mModelIndex so CleanupResources * can release the same one; bit 4 goes to unk_3c5 as a behaviour variant. * @@ -13,37 +13,19 @@ * recoverable later. * * The two Init calls keep extern "C" declarations with scalar slots: both - * carry Fix12 BY VALUE in their real signatures, which mwccarm passes + * carry int BY VALUE in their real signatures, which mwccarm passes * differently at the call site, so spelling the true types breaks the byte * match -- notes/mwccarm-codegen.md 6az. */ #include "KoopaShell.h" -typedef int Fix12; struct BMD_File; -struct SharedFilePtr { int h; }; struct Actor; struct Vector3_16; -struct Model { - static BMD_File* LoadFile(SharedFilePtr& f); -}; -struct ModelBase { - int SetFile(BMD_File* f, int a, int b); -}; -struct ShadowModel { - int InitCylinder(); -}; -struct MovingCylinderClsn { - void Init(Actor* a, Fix12 r, Fix12 h, unsigned int d, unsigned int e); -}; -extern "C" void _ZN18MovingCylinderClsn4InitEP5Actor5Fix12IiES3_jj(void *, Actor* a, Fix12 r, Fix12 h, unsigned int d, unsigned int e); +extern "C" void _ZN18MovingCylinderClsn4InitEP5Actor5Fix12IiES3_jj(void *, Actor* a, int r, int h, unsigned int d, unsigned int e); -struct WithMeshClsn { - void Init(Actor* a, Fix12 b, Fix12 c, Vector3_16* d, Fix12 e); - void StartDetectingWater(); -}; -extern "C" void _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_(void *, Actor* a, Fix12 b, Fix12 c, Vector3_16* d, Fix12 e); +extern "C" void _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_(void *, Actor* a, int b, int c, Vector3_16* d, int e); extern "C" void func_ov102_0214d1f8(void* c, void* p); @@ -53,9 +35,9 @@ extern void* data_ov102_0214ea68; int KoopaShell::InitResources() { BMD_File* bmd; - mModelIndex = (unsigned char)(mSpawnParam & 1); - unk_3c5 = (unsigned char)((mSpawnParam >> 4) & 1); - bmd = Model::LoadFile(*data_ov102_0214d70c[mModelIndex]); + mModelIndex = (unsigned char)(param1 & 1); + unk_3c5 = (unsigned char)((param1 >> 4) & 1); + bmd = (BMD_File *)Model::LoadFile(*data_ov102_0214d70c[mModelIndex]); if (((ModelBase*)&mModel)->SetFile(bmd, 1, 1) == 0) return 0; if (((ShadowModel*)&mShadowModel)->InitCylinder() == 0) @@ -64,8 +46,8 @@ int KoopaShell::InitResources() mSpawnPosX = mPosX; mSpawnPosY = mPosY; mSpawnPosZ = mPosZ; - mSpeed = -0x2000; - unk_0a0 = -0x32000; + mVertAccel = -0x2000; + mTerminalVelocity = -0x32000; unk_100 = 0x14; unk_3c0 = 0; _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_((WithMeshClsn*)&mMeshClsn, (Actor*)this, 0x28000, 0x28000, 0, 0); diff --git a/src/_ZN10KoopaShell8BehaviorEv.cpp b/src/_ZN10KoopaShell8BehaviorEv.cpp index d0ec40867..d5a2583c3 100644 --- a/src/_ZN10KoopaShell8BehaviorEv.cpp +++ b/src/_ZN10KoopaShell8BehaviorEv.cpp @@ -17,7 +17,7 @@ * and null-checked before the call -- a null tick reads as "keep going", and * any state returning 0 ends the frame early. * - * Terrain only matters while mSpeed is non-zero. Hitting a wall in the spat-out + * Terrain only matters while mVertAccel is non-zero. Hitting a wall in the spat-out * state kills the shell (and returns 0, the one non-1 exit); landing in the * rolling state zeroes both speeds. Two other states are exempt from the * on-ground call entirely. @@ -102,7 +102,7 @@ int KoopaShell::Behavior() func_ov102_0214cbec(c); - if (mSpeed != 0) { + if (mVertAccel != 0) { _ZN5Actor9UpdatePosEP12CylinderClsn(c, (char *)&mCylinderClsn); _ZN5Enemy12UpdateWMClsnER12WithMeshClsnj(c, (char *)&mMeshClsn, 0); if (_ZNK12WithMeshClsn10IsOnGroundEv((char *)&mMeshClsn) != 0 || @@ -116,7 +116,7 @@ int KoopaShell::Behavior() } if (_ZNK12WithMeshClsn10IsOnGroundEv((char *)&mMeshClsn) != 0) { if (mState == (void *)&data_ov102_0214ea68) { - mSpeed = 0; + mVertAccel = 0; mVertSpeed = 0; } if (mState != (void *)&data_ov102_0214ea48 && diff --git a/src/_ZN10MrBlizzard13InitResourcesEv.cpp b/src/_ZN10MrBlizzard13InitResourcesEv.cpp index 710b55530..527caa63e 100644 --- a/src/_ZN10MrBlizzard13InitResourcesEv.cpp +++ b/src/_ZN10MrBlizzard13InitResourcesEv.cpp @@ -43,15 +43,15 @@ int MrBlizzard::InitResources() _ZN9ModelBase7SetFileEP8BMD_Fileii(((char *)this) + 0x30c, _ZN5Model8LoadFileER13SharedFilePtr(&data_ov081_02128db0), 1, -1); _ZN5Model8LoadFileER13SharedFilePtr(&data_ov081_02128d90); - _ZN11ShadowModel12InitCylinderEv((char *)&mShadowModel); + _ZN11ShadowModel12InitCylinderEv((char *)&(*(u8 *)&mShadowModel)); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov081_02128d98); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov081_02128db8); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov081_02128da8); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov081_02128d88); _ZN9Animation8LoadFileER13SharedFilePtr(&data_ov081_02128da0); - mPathId = mParam & 0xff; - mType = (mParam & 0xff00) >> 8; + mPathId = (*(s32 *)¶m1) & 0xff; + mType = ((*(s32 *)¶m1) & 0xff00) >> 8; if (mPathId == 0xff) mPathId = 0; if (mType == 0xff) @@ -88,7 +88,7 @@ int MrBlizzard::InitResources() mScaleX = 0x1000; mScaleY = 0x1000; mScaleZ = 0x1000; - unk_0a0 = -0xc8000; + mTerminalVelocity = -0xc8000; v.x = data_ov081_02128998.x; v.y = data_ov081_02128998.y; @@ -110,8 +110,8 @@ int MrBlizzard::InitResources() _ZN7PathPtr6FromIDEj(pp, mPathId); _ZNK7PathPtr7GetNodeER7Vector3j(pp, ((char *)this) + 0x5c, unk_424); unk_424 = 1; - unk_09c = -0x2000; - unk_0b0 = 0x10000000; + mVertAccel = -0x2000; + (*(s32 *)&mFlags) = 0x10000000; func_ov081_02125488(((char *)this), &data_ov081_02128e54); } else { *(s32 *)(((int)((char *)this) + 0x60)) -= 0x118000; @@ -119,12 +119,12 @@ int MrBlizzard::InitResources() if (mType == 3) { unk_108 = 0; unk_10a = 0; - unk_0b0 = 2; + (*(s32 *)&mFlags) = 2; } if (mType == 2) - unk_0b0 = 0x8000002; + (*(s32 *)&mFlags) = 0x8000002; else - unk_0b0 = 3; + (*(s32 *)&mFlags) = 3; } return 1; diff --git a/src/_ZN10PyramidTop16CleanupResourcesEv.cpp b/src/_ZN10PyramidTop16CleanupResourcesEv.cpp index 227981d62..dc89bd40e 100644 --- a/src/_ZN10PyramidTop16CleanupResourcesEv.cpp +++ b/src/_ZN10PyramidTop16CleanupResourcesEv.cpp @@ -10,7 +10,7 @@ extern int data_ov024_02113968[]; int PyramidTop::CleanupResources() { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(data_ov024_02113968))->Release(); ((SharedFilePtr *)(data_ov024_02113960))->Release(); return 1; diff --git a/src/_ZN10PyramidTop8BehaviorEv.cpp b/src/_ZN10PyramidTop8BehaviorEv.cpp index fb5ce15fe..8618b6a6a 100644 --- a/src/_ZN10PyramidTop8BehaviorEv.cpp +++ b/src/_ZN10PyramidTop8BehaviorEv.cpp @@ -22,13 +22,13 @@ int PyramidTop::Behavior() case 1: _ZN5Sound15PlaySecretSoundEP5ActorPt(((char*)this), (void*)((char*)&unk_3b4)); if (unk_3b2 == 0) { - _ZN5Sound9PlayBank3EjRK7Vector3(0x4b, (void*)((char*)&unk_074)); + _ZN5Sound9PlayBank3EjRK7Vector3(0x4b, (void*)((char*)&mCamSpacePosX)); } func_ov024_02111350(((char*)this)); break; case 2: if (_ZN5Sound15PlaySecretSoundEP5ActorPt(((char*)this), (void*)((char*)&unk_3b4))) { - _ZN5Sound9PlayBank3EjRK7Vector3(0x4c, (void*)((char*)&unk_074)); + _ZN5Sound9PlayBank3EjRK7Vector3(0x4c, (void*)((char*)&mCamSpacePosX)); func_ov024_021112c0(((char*)this)); } else { func_ov024_02111350(((char*)this)); diff --git a/src/_ZN10SlidingIce16CleanupResourcesEv.cpp b/src/_ZN10SlidingIce16CleanupResourcesEv.cpp index 4bb8584fb..69ab155e9 100644 --- a/src/_ZN10SlidingIce16CleanupResourcesEv.cpp +++ b/src/_ZN10SlidingIce16CleanupResourcesEv.cpp @@ -9,8 +9,8 @@ extern char data_ov027_02113be0[]; int SlidingIce::CleanupResources() { - unsigned char ok = (mActorID==0x5d); - if(ok){ ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); } + unsigned char ok = (actorID==0x5d); + if(ok){ ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(data_ov027_02113be8))->Release(); ((SharedFilePtr *)(data_ov027_02113be0))->Release(); return 1; diff --git a/src/_ZN10SlidingIce6RenderEv.cpp b/src/_ZN10SlidingIce6RenderEv.cpp index 758358867..d6479bdfe 100644 --- a/src/_ZN10SlidingIce6RenderEv.cpp +++ b/src/_ZN10SlidingIce6RenderEv.cpp @@ -17,7 +17,7 @@ void _ZN8Platform19UpdateClsnPosAndRotEv(void*); int SlidingIce::Render() { - int x = mActorID==0x5d; + int x = actorID==0x5d; if(x){ _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); diff --git a/src/_ZN10SlidingIce8BehaviorEv.cpp b/src/_ZN10SlidingIce8BehaviorEv.cpp index 08d9ad460..081a1d4ae 100644 --- a/src/_ZN10SlidingIce8BehaviorEv.cpp +++ b/src/_ZN10SlidingIce8BehaviorEv.cpp @@ -16,10 +16,10 @@ extern int _ZN5Actor5SpawnEjjRK7Vector3PK10Vector3_16as(unsigned int, unsigned i int SlidingIce::Behavior() { - int isType = (mActorID == 0x5d); + int isType = (actorID == 0x5d); if(isType){ if(DecIfAbove0_Short((char *)&unk_31e) == 0){ - _Z14ApproachLinearRiii((int*)((char *)&unk_098), 0, 0x3000); + _Z14ApproachLinearRiii((int*)((char *)&mHorzSpeed), 0, 0x3000); if(_Z14ApproachLinearRiii((int*)((char *)&mPosY), unk_324, 0xa000) != 0){ _ZN9ActorBase18MarkForDestructionEv(((char *)this)); } diff --git a/src/_ZN10StarSwitch16CleanupResourcesEv.cpp b/src/_ZN10StarSwitch16CleanupResourcesEv.cpp index f5c5c995b..b0595dc30 100644 --- a/src/_ZN10StarSwitch16CleanupResourcesEv.cpp +++ b/src/_ZN10StarSwitch16CleanupResourcesEv.cpp @@ -17,8 +17,8 @@ extern char data_ov002_0211092c; int StarSwitch::CleanupResources() { int t; - if (((MeshColliderBase *)((char*)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char*)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(*(void**)(&data_ov002_021098e8 + unk_34c * 0xc)))->Release(); ((SharedFilePtr *)(*(void**)(&data_ov002_021098ec + unk_34c * 0xc)))->Release(); diff --git a/src/_ZN10StarSwitch8BehaviorEv.cpp b/src/_ZN10StarSwitch8BehaviorEv.cpp index f95861edc..2897a3c47 100644 --- a/src/_ZN10StarSwitch8BehaviorEv.cpp +++ b/src/_ZN10StarSwitch8BehaviorEv.cpp @@ -23,7 +23,7 @@ int StarSwitch::Behavior() int v; if (IsAreaShowing(unk_353) == 0) { - mAreaId = unk_353; + (*(u8 *)&mAreaId) = unk_353; unk_338 = 1; func_ov002_020ba01c(((char *)this), 2, 1, 0x333, 0x1000); func_ov002_020ba4d8(((char *)this), 0); @@ -57,7 +57,7 @@ int StarSwitch::Behavior() } if (_ZN5Actor10FindWithIDEj(id344) == 0) { mTargetActorID = 0; - mAreaId = unk_353; + (*(u8 *)&mAreaId) = unk_353; return 1; } } diff --git a/src/_ZN10StarSwitchD1Ev.cpp b/src/_ZN10StarSwitchD1Ev.cpp index aa9a51b8d..dde1988f1 100644 --- a/src/_ZN10StarSwitchD1Ev.cpp +++ b/src/_ZN10StarSwitchD1Ev.cpp @@ -2,12 +2,11 @@ // @symbol _ZN10StarSwitchD1Ev /* recovered: real C++ destructor -- the compiler emits the whole body * - * Two vtable stores and three destructor calls, all of them consequences of + * Two vtable stores and three destructor calls, every one a consequence of * `struct StarSwitch : Platform`: its own vptr, then Platform's -- inlined, * because Platform's destructor is defined in its class body -- then - * Platform's Model and MovingMeshCollider, then Actor. - * - * This class adds no member with a destructor, so it contributes nothing. + * Platform's Model and MovingMeshCollider, then Actor. This class adds no + * member with a destructor of its own. */ #include "StarSwitch.h" diff --git a/src/_ZN11CannonHatch13InitResourcesEv.cpp b/src/_ZN11CannonHatch13InitResourcesEv.cpp index 20c47af05..bfb9434ab 100644 --- a/src/_ZN11CannonHatch13InitResourcesEv.cpp +++ b/src/_ZN11CannonHatch13InitResourcesEv.cpp @@ -27,7 +27,7 @@ int CannonHatch::InitResources() { struct KCL_File *kcl = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov002_0210e124); _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - ((unsigned char *)this) + 0x124, kcl, *(struct Matrix4x3 *)((unsigned char *)&unk_2ec), 0x199, + ((unsigned char *)this) + 0x124, kcl, *(struct Matrix4x3 *)((unsigned char *)&(*(u8 *)&mClsnMat)), 0x199, mAngleY, data_ov002_0210d7f4); } unk_320 = mPosX; diff --git a/src/_ZN11CannonHatch6RenderEv.cpp b/src/_ZN11CannonHatch6RenderEv.cpp index db1478230..53c9013e6 100644 --- a/src/_ZN11CannonHatch6RenderEv.cpp +++ b/src/_ZN11CannonHatch6RenderEv.cpp @@ -15,7 +15,7 @@ struct Obj { int CannonHatch::Render() { - if (data_0209f2f8 == 6 && data_0209f220 == 1 && (*(int*)((char*)&mParam) & 0xff) == 1) + if (data_0209f2f8 == 6 && data_0209f220 == 1 && (*(int*)((char*)¶m1) & 0xff) == 1) return 1; if (*(unsigned char*)((char*)&unk_32e) != 0) return 1; diff --git a/src/_ZN11ChiefChilly13InitResourcesEv.cpp b/src/_ZN11ChiefChilly13InitResourcesEv.cpp index 2b837fe8f..d6da9f9e6 100644 --- a/src/_ZN11ChiefChilly13InitResourcesEv.cpp +++ b/src/_ZN11ChiefChilly13InitResourcesEv.cpp @@ -50,8 +50,8 @@ int ChiefChilly::InitResources() f = _ZN5Model8LoadFileER13SharedFilePtr(&data_ov073_02123298); _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this)+0x30c, f, 1, -1); _ZN11ShadowModel12InitCylinderEv((char*)&mShadowModel); - unk_09c = -0x3000; - unk_0a0 = -0x3c000; + mVertAccel = -0x3000; + mTerminalVelocity = -0x3c000; v.x = data_ov073_02123040.x; v.y = data_ov073_02123040.y; v.z = data_ov073_02123040.z; diff --git a/src/_ZN11ChiefChilly8BehaviorEv.cpp b/src/_ZN11ChiefChilly8BehaviorEv.cpp index 581d30f4a..627a36f0c 100644 --- a/src/_ZN11ChiefChilly8BehaviorEv.cpp +++ b/src/_ZN11ChiefChilly8BehaviorEv.cpp @@ -7,8 +7,8 @@ * gates five separate things rather than one: * * three states use UpdatePosWithOnlySpeed instead of UpdatePos, and - * apply gravity by hand first: unk_0a8 becomes - * max(unk_0a0, unk_0a8 + unk_09c) + * apply gravity by hand first: mVertSpeed becomes + * max(mTerminalVelocity, mVertSpeed + mVertAccel) * two states at animation frame 7, build a world matrix from the * model's own bone and spawn the landing dust there -- * the impact is tied to the ANIMATION, not to contact @@ -92,7 +92,11 @@ int ChiefChilly::Behavior() int line[0x1f]; *(C **)((char *)data_0209f318 + 0x114) = c; - DecIfAbove0_Short(&unk_100); + /* Enemy declares unk_100 as s16 -- 28 of its subclasses' generated headers + say so -- while this file's own extern for the helper says u16*. Both are + recovered guesses and nothing here settles which; the cast reproduces the + ROM without asserting either. */ + DecIfAbove0_Short((unsigned short *)&unk_100); if (*(void **)((char *)c->pp + 8) != 0) { PMF *p = c->pp + 1; @@ -104,11 +108,11 @@ int ChiefChilly::Behavior() && (char *)c->pp != data_ov073_02123340) { _ZN5Actor9UpdatePosEP12CylinderClsn(self, &mMovingCylinderClsnWithPos); } else { - int sum = unk_0a8 + unk_09c; - int m = unk_0a0; + int sum = mVertSpeed + mVertAccel; + int m = mTerminalVelocity; int ac = unk_0ac; if (sum >= m) m = sum; - unk_0a8 = m; + mVertSpeed = m; unk_0ac = ac; _ZN5Actor22UpdatePosWithOnlySpeedEP12CylinderClsn(self, &mMovingCylinderClsnWithPos); } @@ -172,7 +176,7 @@ int ChiefChilly::Behavior() } _ZN11RaycastLine13SetObjAndLineERK7Vector3S2_P5Actor(line, &rp.start, &rp.end, self); if (_ZN11RaycastLine10DetectClsnEv(line) == 0) { - if (unk_098 > 0xa000) { + if (mHorzSpeed > 0xa000) { unk_4c9 = 1; } unk_4ec = mPosX; @@ -182,7 +186,7 @@ int ChiefChilly::Behavior() mPosX = unk_068; mPosY = unk_06c; mPosZ = unk_070; - unk_098 = 0; + mHorzSpeed = 0; } } else { unk_4c9 = 0; diff --git a/src/_ZN11ChiefChillyD0Ev.c b/src/_ZN11ChiefChillyD0Ev.c deleted file mode 100644 index a13893688..000000000 --- a/src/_ZN11ChiefChillyD0Ev.c +++ /dev/null @@ -1,26 +0,0 @@ -// @symbol _ZN11ChiefChillyD0Ev -/* recovered: named members + shared header */ -#include "ChiefChilly.h" -extern int __destroy_arr(void* c, int a, int b, void* d); -extern void* _ZTV11ChiefChilly[]; -extern void func_020072c0(void); -extern int _ZN11ShadowModelD1Ev(void* c); -extern int _ZN14BlendModelAnimD1Ev(void* c); -extern int _ZN12WithMeshClsnD1Ev(void* c); -extern int _ZN25MovingCylinderClsnWithPosD1Ev(void* c); -extern int _ZN5EnemyD2Ev(int* x); -extern int data_020a0eac; -extern int _ZN6Memory10DeallocateEPvP4Heap(void* p, void* h); -int _ZN11ChiefChillyD0Ev(struct ChiefChilly *self) { - *(void**)((void*)self) = _ZTV11ChiefChilly; - __destroy_arr((char*)((void*)self)+0x4d4, 2, 0xc, (void*)func_020072c0); - __destroy_arr((char*)((void*)self)+0x448, 8, 0xc, (void*)func_020072c0); - __destroy_arr((char*)((void*)self)+0x3e8, 8, 0xc, (void*)func_020072c0); - _ZN11ShadowModelD1Ev((char*)&self->mShadowModel); - _ZN14BlendModelAnimD1Ev((char*)&self->mBlendModelAnim); - _ZN12WithMeshClsnD1Ev((char*)&self->mWithMeshClsn); - _ZN25MovingCylinderClsnWithPosD1Ev((char*)&self->mMovingCylinderClsnWithPos); - _ZN5EnemyD2Ev((int*)((void*)self)); - _ZN6Memory10DeallocateEPvP4Heap(((void*)self), (void*)data_020a0eac); - return (int)((void*)self); -} diff --git a/src/_ZN11ChiefChillyD0Ev.cpp b/src/_ZN11ChiefChillyD0Ev.cpp new file mode 100644 index 000000000..640fbd615 --- /dev/null +++ b/src/_ZN11ChiefChillyD0Ev.cpp @@ -0,0 +1,18 @@ +//cpp +// @symbol _ZN11ChiefChillyD0Ev +/* recovered: real C++ deleting destructor -- the compiler emits the whole body + * + * D0 is the DELETING destructor: destroy through this class and its bases -- + * which is why more than one vptr store appears -- then return the object to + * its heap. Nobody writes that; declaring `~ChiefChilly()` is enough, because mwcc + * emits D2, D0 and D1 together and objisolate keeps the one this file is bound + * to. + * + * The deallocation is an inline operator delete, which is why nothing below + * mentions a heap. + */ +#include "ChiefChilly.h" + +ChiefChilly::~ChiefChilly() +{ +} diff --git a/src/_ZN11ChiefChillyD1Ev.c b/src/_ZN11ChiefChillyD1Ev.c deleted file mode 100644 index 905cb3fc6..000000000 --- a/src/_ZN11ChiefChillyD1Ev.c +++ /dev/null @@ -1,24 +0,0 @@ -// @symbol _ZN11ChiefChillyD1Ev -/* recovered: named members + shared header, declarations from a shared header */ -#include "decl_BlendModelAnim.h" -#include "decl_ShadowModel.h" -#include "decl_WithMeshClsn.h" -/* recovered: named members + shared header */ -#include "ChiefChilly.h" -extern int __destroy_arr(void* p, int a, int b, void* d); -extern void _ZN25MovingCylinderClsnWithPosD1Ev(void* p); -extern int _ZN5EnemyD2Ev(int* x); -extern int func_020072c0; -extern int _ZTV11ChiefChilly[]; -int _ZN11ChiefChillyD1Ev(struct ChiefChilly *self) { - *(int**)((int*)self) = _ZTV11ChiefChilly; - __destroy_arr((char*)((int*)self)+0x4d4, 2, 0xc, &func_020072c0); - __destroy_arr((char*)((int*)self)+0x448, 8, 0xc, &func_020072c0); - __destroy_arr((char*)((int*)self)+0x3e8, 8, 0xc, &func_020072c0); - _ZN11ShadowModelD1Ev((char*)&self->mShadowModel); - _ZN14BlendModelAnimD1Ev((char*)&self->mBlendModelAnim); - _ZN12WithMeshClsnD1Ev((char*)&self->mWithMeshClsn); - _ZN25MovingCylinderClsnWithPosD1Ev((char*)&self->mMovingCylinderClsnWithPos); - _ZN5EnemyD2Ev(((int*)self)); - return (int)((int*)self); -} diff --git a/src/_ZN11ChiefChillyD1Ev.cpp b/src/_ZN11ChiefChillyD1Ev.cpp new file mode 100644 index 000000000..4c5f9048c --- /dev/null +++ b/src/_ZN11ChiefChillyD1Ev.cpp @@ -0,0 +1,22 @@ +//cpp +// @symbol _ZN11ChiefChillyD1Ev +/* recovered: real C++ destructor -- the compiler emits the whole body + * + * Three array cleanups, four member destructors and the chain into Enemy, all + * of it reverse declaration order out of ChiefChilly.h. Nothing here is + * written by hand. + * + * The arrays are what took the longest to name. The ROM destroys them with + * __destroy_arr(this + 0x3e8, 8, 0xc, _ZN7Vector3D1Ev), and a POD array needs no + * cleanup at all -- so the element type had to be a 0xc class with a declared + * destructor. It is Vector3: InitResources fills each element as x/y/z from + * the actor's position, and 0x020072c0 is four bytes of `bx lr`, an empty + * destructor, now named _ZN7Vector3D1Ev in config/arm9/symbols.txt. + * __destroy_arr is __cxa_vec_cleanup (PR #1353), which is what the compiler + * emits here. + */ +#include "ChiefChilly.h" + +ChiefChilly::~ChiefChilly() +{ +} diff --git a/src/_ZN11PyramidLiftD0Ev.c b/src/_ZN11PyramidLiftD0Ev.c index 9e4aa3a87..ff22772cf 100644 --- a/src/_ZN11PyramidLiftD0Ev.c +++ b/src/_ZN11PyramidLiftD0Ev.c @@ -7,12 +7,12 @@ extern int _ZN18MovingMeshColliderD1Ev(void *p); extern int _ZN5ActorD2Ev(void *p); extern int _ZN6Memory10DeallocateEPvP4Heap(void *p, void *h); extern int _ZTV11PyramidLift[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int _ZTV8Platform[]; extern int *data_020a0eac; int _ZN11PyramidLiftD0Ev(struct PyramidLift *self) { *(int**)(((char *)self)) = _ZTV11PyramidLift; - __destroy_arr(((char *)self)+0x37c, 0xa, 0xc, func_020072c0); + __destroy_arr(((char *)self)+0x37c, 0xa, 0xc, _ZN7Vector3D1Ev); _ZN5ModelD1Ev((char *)&self->mModel2); *(int**)(((char *)self)) = _ZTV8Platform; _ZN18MovingMeshColliderD1Ev((char *)&self->mMeshCollider); diff --git a/src/_ZN11PyramidLiftD1Ev.cpp b/src/_ZN11PyramidLiftD1Ev.cpp index 334ec0227..809c824f9 100644 --- a/src/_ZN11PyramidLiftD1Ev.cpp +++ b/src/_ZN11PyramidLiftD1Ev.cpp @@ -9,12 +9,12 @@ #include "PyramidLift.h" extern "C" { extern void __destroy_arr(void*,int,int,void*); -extern int func_020072c0(); +extern int _ZN7Vector3D1Ev(); extern int _ZTV8Platform[]; extern int _ZTV11PyramidLift[]; void* _ZN11PyramidLiftD1Ev(struct PyramidLift *self) { *(int**)((char*)self) = _ZTV11PyramidLift; - __destroy_arr(((char*)self)+0x37c, 0xa, 0xc, (void*)func_020072c0); + __destroy_arr(((char*)self)+0x37c, 0xa, 0xc, (void*)_ZN7Vector3D1Ev); _ZN5ModelD1Ev((char*)&self->mModel2); *(int**)((char*)self) = _ZTV8Platform; _ZN18MovingMeshColliderD1Ev((char*)&self->mMeshCollider); diff --git a/src/_ZN11PyramidStep13InitResourcesEv.cpp b/src/_ZN11PyramidStep13InitResourcesEv.cpp index 181dae1a0..602e05a2f 100644 --- a/src/_ZN11PyramidStep13InitResourcesEv.cpp +++ b/src/_ZN11PyramidStep13InitResourcesEv.cpp @@ -28,14 +28,14 @@ int PyramidStep::InitResources() { struct KCL_File *kcl = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov025_02113ab0); _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - ((char *)this) + 0x124, kcl, *(struct Matrix4x3 *)((char *)&unk_374), 0x1000, - unk_08e, data_ov025_02112ce8); + &mMeshCollider, kcl, *(struct Matrix4x3 *)((char *)&unk_374), 0x1000, + mAngleY, data_ov025_02112ce8); } - func_020393d4((int *)((char *)&mMovingMeshCollider), (int)&_ZN16MeshColliderBase22UpdatePosWithTransformERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + func_020393d4((int *)((char *)&(*(u8 *)&mMeshCollider)), (int)&_ZN16MeshColliderBase22UpdatePosWithTransformERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); { int v = 0x5000; - int k = unk_008 & 3; - unk_0a8 = -v; + int k = (*(s32 *)¶m1) & 3; + mVertSpeed = -v; unk_372 = 0; unk_370 = 0; switch (k) { @@ -48,7 +48,7 @@ int PyramidStep::InitResources() case 2: *(int*)(((int)((char *)this) + 0x60)) -= 0x1f4000; unk_372 = 1; - unk_0a8 = v; + mVertSpeed = v; break; } } diff --git a/src/_ZN11PyramidStep16CleanupResourcesEv.cpp b/src/_ZN11PyramidStep16CleanupResourcesEv.cpp index 61829d733..b13376578 100644 --- a/src/_ZN11PyramidStep16CleanupResourcesEv.cpp +++ b/src/_ZN11PyramidStep16CleanupResourcesEv.cpp @@ -11,7 +11,7 @@ extern int data_ov025_02113ab8[]; int PyramidStep::CleanupResources() { - ((MeshColliderBase *)((char *)&mMovingMeshCollider))->Disable(); + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(data_ov025_02113ab8))->Release(); ((SharedFilePtr *)(data_ov025_02113ab0))->Release(); return 1; diff --git a/src/_ZN12FlamethrowerD0Ev.cpp b/src/_ZN12FlamethrowerD0Ev.cpp index 8ad3a4960..2f19cd1a9 100644 --- a/src/_ZN12FlamethrowerD0Ev.cpp +++ b/src/_ZN12FlamethrowerD0Ev.cpp @@ -5,7 +5,7 @@ /* recovered: named members + shared header */ #include "Flamethrower.h" extern "C" { -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int data_020a0eac[]; extern int _ZN19CylinderClsnWithPosD1Ev[]; void __destroy_arr(void*, int, int, void*); @@ -13,7 +13,7 @@ void _ZN5ActorD2Ev(void*); void _ZN6Memory10DeallocateEPvP4Heap(void*, void*); void* _ZN12FlamethrowerD0Ev(char* c){ *(int*)c = (int)_ZTV12Flamethrower; - __destroy_arr(c+0x3a4, 0xc, 0xc, (void*)func_020072c0); + __destroy_arr(c+0x3a4, 0xc, 0xc, (void*)_ZN7Vector3D1Ev); __destroy_arr(c+0xd4, 0xc, 0x3c, (void*)_ZN19CylinderClsnWithPosD1Ev); _ZN5ActorD2Ev(c); _ZN6Memory10DeallocateEPvP4Heap(c, (void*)data_020a0eac[0]); diff --git a/src/_ZN12FlamethrowerD1Ev.cpp b/src/_ZN12FlamethrowerD1Ev.cpp index 646912cb6..92e985620 100644 --- a/src/_ZN12FlamethrowerD1Ev.cpp +++ b/src/_ZN12FlamethrowerD1Ev.cpp @@ -7,11 +7,11 @@ #include "Flamethrower.h" extern "C" { extern int __destroy_arr(void*, int, int, void*); -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int _ZN19CylinderClsnWithPosD1Ev(); int _ZN12FlamethrowerD1Ev(char* c){ *(int**)c = _ZTV12Flamethrower; - __destroy_arr((char*)c+0x3a4, 0xc, 0xc, (void*)func_020072c0); + __destroy_arr((char*)c+0x3a4, 0xc, 0xc, (void*)_ZN7Vector3D1Ev); __destroy_arr((char*)c+0xd4, 0xc, 0x3c, (void*)&_ZN19CylinderClsnWithPosD1Ev); _ZN5ActorD2Ev(c); return (int)c; diff --git a/src/_ZN12FortressWall13InitResourcesEv.cpp b/src/_ZN12FortressWall13InitResourcesEv.cpp index e460a7847..85e15abe1 100644 --- a/src/_ZN12FortressWall13InitResourcesEv.cpp +++ b/src/_ZN12FortressWall13InitResourcesEv.cpp @@ -20,7 +20,7 @@ int FortressWall::InitResources() int b = (int)(actorID == 0x30); if (b != 0) { unk_31e = 0; - unk_31f = (unsigned char)param1; + unk_31f = (unsigned char)(*(s32 *)¶m1); if (unk_31f == 0xff) unk_31f = 0; } else { diff --git a/src/_ZN12FortressWall16CleanupResourcesEv.cpp b/src/_ZN12FortressWall16CleanupResourcesEv.cpp index 075517cb1..66dc1696e 100644 --- a/src/_ZN12FortressWall16CleanupResourcesEv.cpp +++ b/src/_ZN12FortressWall16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern char data_ov079_0212805c[]; int FortressWall::CleanupResources() { - if(((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if(((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(*(void**)(data_ov079_02128058 + (unsigned char)((char *)this)[0x31e]*0xc)))->Release(); ((SharedFilePtr *)(*(void**)(data_ov079_0212805c + (unsigned char)((char *)this)[0x31e]*0xc)))->Release(); return 1; diff --git a/src/_ZN12FortressWallD1Ev.cpp b/src/_ZN12FortressWallD1Ev.cpp index 5f7b9eec1..69cd68f09 100644 --- a/src/_ZN12FortressWallD1Ev.cpp +++ b/src/_ZN12FortressWallD1Ev.cpp @@ -6,7 +6,7 @@ * `struct FortressWall : Platform`: its own vptr, then Platform's -- inlined, * because Platform's destructor is defined in its class body -- then * Platform's Model and MovingMeshCollider, then Actor. This class adds no - * member with a destructor. + * member with a destructor of its own. */ #include "FortressWall.h" diff --git a/src/_ZN12SwitchPillar13InitResourcesEv.cpp b/src/_ZN12SwitchPillar13InitResourcesEv.cpp index 255b80e3b..f77e53033 100644 --- a/src/_ZN12SwitchPillar13InitResourcesEv.cpp +++ b/src/_ZN12SwitchPillar13InitResourcesEv.cpp @@ -21,13 +21,13 @@ int SwitchPillar::InitResources() { _ZN5Model8LoadFileER13SharedFilePtr(data_ov012_021124d0); _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov012_021124c8); - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this)+0xd4, data_ov012_021124d0[1], 1, 0x14); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, data_ov012_021124d0[1], 1, 0x14); _ZN18TextureTransformer7PrepareER8BMD_FileR8BTA_File(data_ov012_021124d0[1], data_ov012_02111c24); _ZN18TextureTransformer7SetFileER8BTA_Filei5Fix12IiEj(((char*)this)+0x320, data_ov012_02111c24, 0, 0x1000, 0); _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(((char*)this)+0x124, data_ov012_021124c8[1], ((char*)this)+0x2ec, 0x1000, mAngleY, data_ov012_02111c90); - ((MeshColliderBase *)(((char*)this)+0x124))->Enable((Actor *)(((char*)this))); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(&mMeshCollider, data_ov012_021124c8[1], &mClsnMat, 0x1000, mAngleY, data_ov012_02111c90); + ((MeshColliderBase *)(&mMeshCollider))->Enable((Actor *)(((char*)this))); int v = mPosY - 0x4b0000; mLoweredY = v; if(data_0209caa0[2] & 0x80000){ diff --git a/src/_ZN12SwitchPillar16CleanupResourcesEv.cpp b/src/_ZN12SwitchPillar16CleanupResourcesEv.cpp index 64b728297..33ed1d766 100644 --- a/src/_ZN12SwitchPillar16CleanupResourcesEv.cpp +++ b/src/_ZN12SwitchPillar16CleanupResourcesEv.cpp @@ -10,8 +10,8 @@ extern int data_ov012_021124d0[]; int SwitchPillar::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(data_ov012_021124d0))->Release(); ((SharedFilePtr *)(data_ov012_021124c8))->Release(); diff --git a/src/_ZN12SwitchPillar8BehaviorEv.cpp b/src/_ZN12SwitchPillar8BehaviorEv.cpp index b7ec48e5a..4fa6fb697 100644 --- a/src/_ZN12SwitchPillar8BehaviorEv.cpp +++ b/src/_ZN12SwitchPillar8BehaviorEv.cpp @@ -21,7 +21,7 @@ int SwitchPillar::Behavior() mPosY = mLoweredY; } else if (*(int*)((char*)data_0209caa0 + 8) & 0x80000) { unk_338 = _ZN5Sound8PlayLongEjjjRK7Vector3s( - unk_338, 3, 0x96, (void*)((char*)&unk_074), 0); + unk_338, 3, 0x96, (void*)((char*)&mCamSpacePosX), 0); *(int*)((char*)&mPosY) -= 0x5000; unk_33e = 1; if (mPosY <= mLoweredY) { @@ -32,7 +32,7 @@ int SwitchPillar::Behavior() *(int*)&data_0209f32c = mPosY; _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); - unk_32c = 0x1000; - _ZN9Animation7AdvanceEv((char*)&mTextureTransformer); + (*(s32 *)((char *)&mTextureTransformer + 0xc)) = 0x1000; + _ZN9Animation7AdvanceEv((char*)&(*(u8 *)&mTextureTransformer)); return 1; } diff --git a/src/_ZN12WaterSuction13InitResourcesEv.cpp b/src/_ZN12WaterSuction13InitResourcesEv.cpp index 79698b6bd..bf89031da 100644 --- a/src/_ZN12WaterSuction13InitResourcesEv.cpp +++ b/src/_ZN12WaterSuction13InitResourcesEv.cpp @@ -13,7 +13,7 @@ extern V3 data_ov026_02113f4c; int WaterSuction::InitResources() { V3 vec; - unk_314 = unk_008 & 0xff; + unk_314 = (*(s32 *)¶m1) & 0xff; vec = data_ov026_02113f4c; _ZN25MovingCylinderClsnWithPos4InitEP5ActorRK7Vector35Fix12IiES6_jj(((char*)this) + 0x110, ((char*)this), &vec, 0x64000, 0xa4000, 0x800006, 0); func_ov026_021122d4(((char*)this), &data_ov026_02113f58); diff --git a/src/_ZN12WaterSuction8BehaviorEv.cpp b/src/_ZN12WaterSuction8BehaviorEv.cpp index df21fc4dd..3a5267051 100644 --- a/src/_ZN12WaterSuction8BehaviorEv.cpp +++ b/src/_ZN12WaterSuction8BehaviorEv.cpp @@ -22,17 +22,17 @@ struct C { int WaterSuction::Behavior() { C* c = (C*)((char*)this); - DecIfAbove0_Short((unsigned short*)((char*)&unk_100)); + DecIfAbove0_Short((unsigned short*)((char*)&(*(u8 *)&unk_100))); Obj* o = c->obj; if (*(int*)((char*)o + 8) != 0) { (c->*(o->pmf))(); } _ZN5Actor9UpdatePosEP12CylinderClsn(((char*)this), ((char*)this) + 0x110); - unk_08c = unk_092; - unk_08e = unk_094; - unk_090 = unk_096; + mAngleX = mPrevAngleX; + mAngleY = mPrevAngleY; + mAngleZ = mPrevAngleZ; func_ov026_02112324(((char*)this)); - _ZN12CylinderClsn5ClearEv((char*)&mMovingCylinderClsnWithPos); - _ZN12CylinderClsn6UpdateEv((char*)&mMovingCylinderClsnWithPos); + _ZN12CylinderClsn5ClearEv((char*)&(*(MovingCylinderClsnWithPos *)&mMovingCylinderClsnWithPos)); + _ZN12CylinderClsn6UpdateEv((char*)&(*(MovingCylinderClsnWithPos *)&mMovingCylinderClsnWithPos)); return 1; } diff --git a/src/_ZN13BigBrickBlock16CleanupResourcesEv.cpp b/src/_ZN13BigBrickBlock16CleanupResourcesEv.cpp index 55f8fc0be..9c2bbb06a 100644 --- a/src/_ZN13BigBrickBlock16CleanupResourcesEv.cpp +++ b/src/_ZN13BigBrickBlock16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern char data_ov002_02108ab4[]; int BigBrickBlock::CleanupResources() { - if(((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if(((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(*(void**)(data_ov002_02108ab0 + (unsigned char)((char *)this)[0x32c]*0xc)))->Release(); ((SharedFilePtr *)(*(void**)(data_ov002_02108ab4 + (unsigned char)((char *)this)[0x32c]*0xc)))->Release(); return 1; diff --git a/src/_ZN13BigBrickBlock8BehaviorEv.cpp b/src/_ZN13BigBrickBlock8BehaviorEv.cpp index a676b69e9..81b4f1349 100644 --- a/src/_ZN13BigBrickBlock8BehaviorEv.cpp +++ b/src/_ZN13BigBrickBlock8BehaviorEv.cpp @@ -29,11 +29,11 @@ int BigBrickBlock::Behavior() } if (_ZN5Event6GetBitEj(mEventID) == 0 || unk_31e != 0) { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled() != 0) - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled() != 0) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } else { - func_020393a4((int *)((char *)&mMeshCollider), 0x15e000); - func_02039394((int *)((char *)&mMeshCollider), 0x64000); + func_020393a4((int *)((char *)&(*(u8 *)&mMeshCollider)), 0x15e000); + func_02039394((int *)((char *)&(*(u8 *)&mMeshCollider)), 0x64000); _ZN8Platform21IsClsnInRangeOnScreenE5Fix12IiES1_(((char *)this), 0x150000, 0); } @@ -48,8 +48,8 @@ int BigBrickBlock::Behavior() v1 = 0x1c2000; v5 = 0x96000; } - func_020393a4((int *)((char *)&mMeshCollider), v1); - func_02039394((int *)((char *)&mMeshCollider), v5); + func_020393a4((int *)((char *)&(*(u8 *)&mMeshCollider)), v1); + func_02039394((int *)((char *)&(*(u8 *)&mMeshCollider)), v5); _ZN8Platform21IsClsnInRangeOnScreenE5Fix12IiES1_(((char *)this), 0x600000, 0); } return 1; diff --git a/src/_ZN13BigBrickBlockD1Ev.cpp b/src/_ZN13BigBrickBlockD1Ev.cpp index b3119a509..4c8fb3d4c 100644 --- a/src/_ZN13BigBrickBlockD1Ev.cpp +++ b/src/_ZN13BigBrickBlockD1Ev.cpp @@ -6,7 +6,7 @@ * `struct BigBrickBlock : Platform`: its own vptr, then Platform's -- inlined, * because Platform's destructor is defined in its class body -- then * Platform's Model and MovingMeshCollider, then Actor. This class adds no - * member with a destructor. + * member with a destructor of its own. */ #include "BigBrickBlock.h" diff --git a/src/_ZN13FortressTower16CleanupResourcesEv.cpp b/src/_ZN13FortressTower16CleanupResourcesEv.cpp index 6b76d9c66..68ddd5f99 100644 --- a/src/_ZN13FortressTower16CleanupResourcesEv.cpp +++ b/src/_ZN13FortressTower16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern char data_ov102_0214e18c[]; int FortressTower::CleanupResources() { - if(((MeshColliderBase *)((char *)&mMovingMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMovingMeshCollider))->Disable(); + if(((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(*(void**)(data_ov102_0214e188 + (unsigned char)((char *)this)[0x31e]*0xc)))->Release(); ((SharedFilePtr *)(*(void**)(data_ov102_0214e18c + (unsigned char)((char *)this)[0x31e]*0xc)))->Release(); return 1; diff --git a/src/_ZN13FortressTower8BehaviorEv.cpp b/src/_ZN13FortressTower8BehaviorEv.cpp index ffe008328..4f1a2ab79 100644 --- a/src/_ZN13FortressTower8BehaviorEv.cpp +++ b/src/_ZN13FortressTower8BehaviorEv.cpp @@ -10,7 +10,7 @@ extern unsigned char data_0209f2d8[]; int FortressTower::Behavior() { - unsigned short id = unk_00c; + unsigned short id = actorID; int r1 = 0; switch (id) { case 0x31: r1 = 0x900000; break; @@ -22,8 +22,8 @@ int FortressTower::Behavior() } int on = (data_0209f2d8[0] == 1); if (on) { - if (!((MeshColliderBase *)((char*)&mMovingMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char*)((char*)this)+0x124))->Enable((Actor *)(((char*)this))); + if (!((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char*)&mMeshCollider))->Enable((Actor *)(((char*)this))); } else { _ZN8Platform21IsClsnInRangeOnScreenE5Fix12IiES1_(((char*)this), r1, 0); } diff --git a/src/_ZN13MontyMoleRock13InitResourcesEv.cpp b/src/_ZN13MontyMoleRock13InitResourcesEv.cpp index 91474d5a9..972202e81 100644 --- a/src/_ZN13MontyMoleRock13InitResourcesEv.cpp +++ b/src/_ZN13MontyMoleRock13InitResourcesEv.cpp @@ -10,23 +10,23 @@ int _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_(void*,void*,int,i extern int data_ov080_021283c8[]; } -int MontyMoleRock::InitResources() +s32 MontyMoleRock::InitResources() { int m = _ZN5Model8LoadFileER13SharedFilePtr(data_ov080_021283c8); if(_ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this)+0x110, m, 1, -1) == 0) return 0; _ZN18MovingCylinderClsn4InitEP5Actor5Fix12IiES3_jj(((char*)this)+0x160, ((char*)this), 0x1e000, 0x1e000, 0x200004, 0); - unk_350 = unk_008 & 1; + unk_350 = (*(s32 *)¶m1) & 1; _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_(((char*)this)+0x194, ((char*)this), 0x1e000, 0x1e000, 0, 0); - unk_09c = -0x2000; - unk_0a0 = -0x3c000; + mVertAccel = -0x2000; + mTerminalVelocity = -0x3c000; if(unk_350 == 0){ - unk_080 = 0x1000; - unk_084 = 0x1000; - unk_088 = 0x1000; + mScaleX = 0x1000; + mScaleY = 0x1000; + mScaleZ = 0x1000; } else { - unk_080 = 0x800; - unk_084 = 0x800; - unk_088 = 0x800; + mScaleX = 0x800; + mScaleY = 0x800; + mScaleZ = 0x800; } return 1; } diff --git a/src/_ZN13MontyMoleRock6RenderEv.cpp b/src/_ZN13MontyMoleRock6RenderEv.cpp index 2248b9a65..ffef8c7de 100644 --- a/src/_ZN13MontyMoleRock6RenderEv.cpp +++ b/src/_ZN13MontyMoleRock6RenderEv.cpp @@ -6,9 +6,9 @@ extern "C" { struct Base{ virtual void v0(); virtual void v1(); virtual void v2(); virtual void v3(); virtual void v4(); virtual void m(void*); }; } -int MontyMoleRock::Render() +s32 MontyMoleRock::Render() { - Base*b=(Base*)((char*)&mModel); - b->m((char*)&unk_080); + Base*b=(Base*)((char*)&(*(Model *)&mModel)); + b->m((char*)&mScaleX); return 1; } diff --git a/src/_ZN13MontyMoleRock8BehaviorEv.cpp b/src/_ZN13MontyMoleRock8BehaviorEv.cpp index 04efc4f0a..1c8c0453f 100644 --- a/src/_ZN13MontyMoleRock8BehaviorEv.cpp +++ b/src/_ZN13MontyMoleRock8BehaviorEv.cpp @@ -9,7 +9,7 @@ extern "C" int RandomIntInternal(int *seed); extern int data_0209e650; -int MontyMoleRock::Behavior() +s32 MontyMoleRock::Behavior() { unsigned char *c = (unsigned char *)((void *)this); unsigned char *o; diff --git a/src/_ZN13PoleBillboard16CleanupResourcesEv.cpp b/src/_ZN13PoleBillboard16CleanupResourcesEv.cpp index ff38f41a7..7d026688c 100644 --- a/src/_ZN13PoleBillboard16CleanupResourcesEv.cpp +++ b/src/_ZN13PoleBillboard16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int PoleBillboard_ModelFile[]; int PoleBillboard::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(PoleBillboard_ModelFile))->Release(); ((SharedFilePtr *)(PoleBillboard_ClsnFile))->Release(); diff --git a/src/_ZN13QuestionBlock16CleanupResourcesEv.cpp b/src/_ZN13QuestionBlock16CleanupResourcesEv.cpp index f30101cad..a9be84741 100644 --- a/src/_ZN13QuestionBlock16CleanupResourcesEv.cpp +++ b/src/_ZN13QuestionBlock16CleanupResourcesEv.cpp @@ -26,17 +26,17 @@ extern char data_ov102_0214e7d0[]; int QuestionBlock::CleanupResources() { int b, b2, b3; - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); - b = (int)(mActorId == 0x16); + b = (int)(actorID == 0x16); if (b) ((SharedFilePtr *)(data_ov002_0210da58))->Release(); - b2 = (int)(mActorId == 0x14); + b2 = (int)(actorID == 0x14); if (b2) goto dosw; - b3 = (int)(mActorId == 0x15); + b3 = (int)(actorID == 0x15); if (b3) { dosw: switch (unk_3f3) { @@ -69,7 +69,7 @@ int QuestionBlock::CleanupResources() } } - switch (mActorId - 0x14) { + switch (actorID - 0x14) { case 0: ((SharedFilePtr *)(data_ov102_0214e7e8))->Release(); ((SharedFilePtr *)(data_ov102_0214e808))->Release(); diff --git a/src/_ZN13QuestionBlock6RenderEv.cpp b/src/_ZN13QuestionBlock6RenderEv.cpp index 6ef35aa69..b8ce2050e 100644 --- a/src/_ZN13QuestionBlock6RenderEv.cpp +++ b/src/_ZN13QuestionBlock6RenderEv.cpp @@ -20,7 +20,7 @@ int QuestionBlock::Render() if (unk_3e8 == 2) goto done; if ((*(int*)((char*)&data_0209caa0 + 4) & 0x80000000) == 0) { - int b = (mActorId == 0x14); + int b = (actorID == 0x14); if (b != 0) { Sub* s = (Sub*)((char*)&mModelAnim); s->m(0); @@ -28,7 +28,7 @@ int QuestionBlock::Render() } } { - Sub* s2 = (Sub*)((char*)&mModel); + Sub* s2 = (Sub*)((char*)&(*(u8 *)&mModel)); s2->m((int)((char*)&mScaleX)); } done: diff --git a/src/_ZN13QuestionBlock8BehaviorEv.cpp b/src/_ZN13QuestionBlock8BehaviorEv.cpp index fc58af02a..4197d9b27 100644 --- a/src/_ZN13QuestionBlock8BehaviorEv.cpp +++ b/src/_ZN13QuestionBlock8BehaviorEv.cpp @@ -25,20 +25,20 @@ int QuestionBlock::Behavior() func_ov102_02149ff0(((char*)this)); func_ov102_02149ea4(((char*)this)); } - func_020393a4((int*)((char*)&mMeshCollider), 0x8c000); - func_02039394((int*)((char*)&mMeshCollider), 0x46000); + func_020393a4((int*)((char*)&(*(u8 *)&mMeshCollider)), 0x8c000); + func_02039394((int*)((char*)&(*(u8 *)&mMeshCollider)), 0x46000); if (unk_3e8 != 0) { - if (((MeshColliderBase *)((char*)&mMeshCollider))->IsEnabled() != 0) { - ((MeshColliderBase *)((char*)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->IsEnabled() != 0) { + ((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->Disable(); } goto end; } if ((data_0209caa0[1] & 0x80000000) == 0) { - int b = (int)(mActorId == 0x14); + int b = (int)(actorID == 0x14); if (b != 0) { _ZN9Animation7AdvanceEv((char*)(Animation *)&mModelAnim); - if (((MeshColliderBase *)((char*)&mMeshCollider))->IsEnabled() != 0) { - ((MeshColliderBase *)((char*)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->IsEnabled() != 0) { + ((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->Disable(); } goto end; } @@ -46,8 +46,8 @@ int QuestionBlock::Behavior() { int b = (int)(data_0209f2d8 == 1); if (b != 0) { - if (((MeshColliderBase *)((char*)&mMeshCollider))->IsEnabled() == 0) { - ((MeshColliderBase *)(((char*)this)+0x124))->Enable((Actor *)(((char*)this))); + if (((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->IsEnabled() == 0) { + ((MeshColliderBase *)(&mMeshCollider))->Enable((Actor *)(((char*)this))); } goto end; } diff --git a/src/_ZN13TTC_MovingBar13InitResourcesEv.cpp b/src/_ZN13TTC_MovingBar13InitResourcesEv.cpp index 87c6f9b21..e07be1397 100644 --- a/src/_ZN13TTC_MovingBar13InitResourcesEv.cpp +++ b/src/_ZN13TTC_MovingBar13InitResourcesEv.cpp @@ -32,8 +32,8 @@ int TTC_MovingBar::InitResources() char raycast[0x50]; int i; - if (mActorID != 0x72) { - if (mActorID == 0x73) + if (actorID != 0x72) { + if (actorID == 0x73) unk_31e = 1; } else { unk_31e = 0; @@ -41,7 +41,7 @@ int TTC_MovingBar::InitResources() i = unk_31e; _ZN9ModelBase7SetFileEP8BMD_Fileii( - ((char *)this) + 0xd4, + &mModel, _ZN5Model8LoadFileER13SharedFilePtr(*(void **)(data_ov065_0211d35c + i * 0xc)), 1, -1); @@ -51,14 +51,14 @@ int TTC_MovingBar::InitResources() i = unk_31e; _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - ((char *)this) + 0x124, + &mMeshCollider, _ZN12MeshCollider8LoadFileER13SharedFilePtr(*(void **)(data_ov065_0211d360 + i * 0xc)), - ((char *)this) + 0x2ec, + &mClsnMat, 0x199, mAngleY, *(void **)(data_ov065_0211d364 + i * 0xc)); - func_020393d4((int *)((char *)&mMeshCollider), (int)&_ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + func_020393d4((int *)((char *)&(*(u8 *)&mMeshCollider)), (int)&_ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); pos.x = mPosX; pos.y = mPosY; diff --git a/src/_ZN13TTC_MovingBar16CleanupResourcesEv.cpp b/src/_ZN13TTC_MovingBar16CleanupResourcesEv.cpp index 27a8c9cba..00fb30b93 100644 --- a/src/_ZN13TTC_MovingBar16CleanupResourcesEv.cpp +++ b/src/_ZN13TTC_MovingBar16CleanupResourcesEv.cpp @@ -9,8 +9,8 @@ int TTC_MovingBar::CleanupResources() { - if(((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if(((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(*(void**)(data_ov065_0211d35c + (unsigned char)((char *)this)[0x31e]*0xc)))->Release(); ((SharedFilePtr *)(*(void**)(data_ov065_0211d360 + (unsigned char)((char *)this)[0x31e]*0xc)))->Release(); return 1; diff --git a/src/_ZN14ArrowSignRight16CleanupResourcesEv.cpp b/src/_ZN14ArrowSignRight16CleanupResourcesEv.cpp index d92b1314b..a0e4bc7dd 100644 --- a/src/_ZN14ArrowSignRight16CleanupResourcesEv.cpp +++ b/src/_ZN14ArrowSignRight16CleanupResourcesEv.cpp @@ -10,8 +10,8 @@ extern char data_ov098_0213c380[]; int ArrowSignRight::CleanupResources() { - if(((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if(((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(*(void**)(data_ov098_0213c380 + (unsigned char)((char *)this)[0x37c]*0xc)))->Release(); ((SharedFilePtr *)(*(void**)(data_ov098_0213c384 + (unsigned char)((char *)this)[0x37c]*0xc)))->Release(); return 1; diff --git a/src/_ZN14ArrowSignRight8BehaviorEv.cpp b/src/_ZN14ArrowSignRight8BehaviorEv.cpp index 0b634d367..ad194544c 100644 --- a/src/_ZN14ArrowSignRight8BehaviorEv.cpp +++ b/src/_ZN14ArrowSignRight8BehaviorEv.cpp @@ -14,8 +14,8 @@ int ArrowSignRight::Behavior() { if (_ZN8Platform20UpdateKillByMegaCharEsss5Fix12IiE(((char*)this), -0x2000, 0, 0, 0x96000)) return 1; - func_02039394((int*)((char*)&mMeshCollider), 0xc0000); - func_020393a4((int*)((char*)&mMeshCollider), 0xe0000); + func_02039394((int*)((char*)&(*(u8 *)&mMeshCollider)), 0xc0000); + func_020393a4((int*)((char*)&(*(u8 *)&mMeshCollider)), 0xe0000); _ZN5Actor18DropShadowScaleXYZER11ShadowModelR9Matrix4x35Fix12IiES5_S5_j( ((char*)this), (void*)((char*)&mShadowModel), (void*)((char*)&unk_348), 0x10e000, 0x64000, 0x46000, 0xf); _ZN8Platform21IsClsnInRangeOnScreenE5Fix12IiES1_(((char*)this), 0x600000, 0); diff --git a/src/_ZN14BlueCoinSwitch13InitResourcesEv.cpp b/src/_ZN14BlueCoinSwitch13InitResourcesEv.cpp index 88f8d8507..363d22002 100644 --- a/src/_ZN14BlueCoinSwitch13InitResourcesEv.cpp +++ b/src/_ZN14BlueCoinSwitch13InitResourcesEv.cpp @@ -7,7 +7,7 @@ * Loads the model and collision mesh, unpacks the spawn word, and computes how * far the switch will sink. * - * mParam carries two fields: bits 0-3 are the event bit to set when the switch + * param1 carries two fields: bits 0-3 are the event bit to set when the switch * bottoms out, bits 8-15 are the countdown seed. That seed is stored in TENTHS * -- it is multiplied by 10 here -- and a byte of 0 or 0xff means "use the * default 0xfa" instead. @@ -63,18 +63,18 @@ int BlueCoinSwitch::InitResources() unsigned short* p; bmd = _ZN5Model8LoadFileER13SharedFilePtr(&data_ov002_02110acc); - _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, bmd, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&(*(u8 *)&mModel), bmd, 1, -1); - unk_32d = (int)mParam & 0xf; + unk_32d = (int)param1 & 0xf; _ZN8Platform21UpdateModelPosAndRotYEv(c); _ZN8Platform19UpdateClsnPosAndRotEv(c); kcl = _ZN12MeshCollider8LoadFileER13SharedFilePtr(&data_ov002_02110ac4); _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - &mMeshCollider, kcl, &mMatrix, 0x199, mAngleY, + &(*(u8 *)&mMeshCollider), kcl, &mClsnMat, 0x199, mAngleY, &data_ov002_0210d6f4); - func_020393c4(&mMeshCollider, (void*)&func_ov002_020f15b8); + func_020393c4(&(*(u8 *)&mMeshCollider), (void*)&func_ov002_020f15b8); unk_32c = 0; @@ -82,7 +82,7 @@ int BlueCoinSwitch::InitResources() and so set_fa rematerializes add r0,r4,#0x300 after ldrh clobbers r0. */ y = mPosY; unk_320 = y - 0x64000; - x = mParam; + x = param1; unk_32a = (x >> 8) & 0xff; unk_32e = mAreaId; val = unk_32a; diff --git a/src/_ZN14BlueCoinSwitch16CleanupResourcesEv.cpp b/src/_ZN14BlueCoinSwitch16CleanupResourcesEv.cpp index aa5037dfe..9e652c058 100644 --- a/src/_ZN14BlueCoinSwitch16CleanupResourcesEv.cpp +++ b/src/_ZN14BlueCoinSwitch16CleanupResourcesEv.cpp @@ -16,8 +16,8 @@ extern void _ZN13SharedFilePtr7ReleaseEv(void *); int BlueCoinSwitch::CleanupResources() { - if (_ZN16MeshColliderBase9IsEnabledEv(&mMeshCollider)) { - _ZN16MeshColliderBase7DisableEv(&mMeshCollider); + if (_ZN16MeshColliderBase9IsEnabledEv(&(*(u8 *)&mMeshCollider))) { + _ZN16MeshColliderBase7DisableEv(&(*(u8 *)&mMeshCollider)); } _ZN13SharedFilePtr7ReleaseEv(BlueCoinSwitch_ModelFile); _ZN13SharedFilePtr7ReleaseEv(BlueCoinSwitch_ClsnFile); diff --git a/src/_ZN14BlueCoinSwitch6RenderEv.cpp b/src/_ZN14BlueCoinSwitch6RenderEv.cpp index 70bc44161..db72fbbe5 100644 --- a/src/_ZN14BlueCoinSwitch6RenderEv.cpp +++ b/src/_ZN14BlueCoinSwitch6RenderEv.cpp @@ -20,7 +20,7 @@ struct Base { int BlueCoinSwitch::Render() { if (mPosY > unk_320) { - Base *bp = (Base *)&mModel; + Base *bp = (Base *)&(*(u8 *)&mModel); bp->m(0); } return 1; diff --git a/src/_ZN14BlueCoinSwitch8BehaviorEv.cpp b/src/_ZN14BlueCoinSwitch8BehaviorEv.cpp index 25d08daa3..cc960e206 100644 --- a/src/_ZN14BlueCoinSwitch8BehaviorEv.cpp +++ b/src/_ZN14BlueCoinSwitch8BehaviorEv.cpp @@ -68,7 +68,7 @@ s32 BlueCoinSwitch::Behavior() mPosY = unk_320; _ZN5Event6SetBitEj(unk_32d); unk_328 = unk_32a; - _ZN16MeshColliderBase7DisableEv(&mMeshCollider); + _ZN16MeshColliderBase7DisableEv(&(*(u8 *)&mMeshCollider)); _ZN5Actor8PoofDustEv(c); } } diff --git a/src/_ZN14KnockDownPlank13InitResourcesEv.cpp b/src/_ZN14KnockDownPlank13InitResourcesEv.cpp index eebfb0d05..395d35bc4 100644 --- a/src/_ZN14KnockDownPlank13InitResourcesEv.cpp +++ b/src/_ZN14KnockDownPlank13InitResourcesEv.cpp @@ -19,25 +19,25 @@ extern int _ZN16MeshColliderBase21UpdatePosWithVelocityERS_P5ActorR10ClsnResultR int KnockDownPlank::InitResources() { - int b = (*(unsigned short*)((char*)&unk_00c) == 0x35) ? 1 : 0; + int b = (*(unsigned short*)((char*)&actorID) == 0x35) ? 1 : 0; if(b) *(int*)((char*)&mVariant) = 1; else *(int*)((char*)&mVariant) = 0; int j0 = *(int*)((char*)&mVariant) * 0xc; int m = _ZN5Model8LoadFileER13SharedFilePtr(*(void**)((char*)data_ov015_02114534 + j0)); - _ZN9ModelBase7SetFileEP8BMD_Fileii((char*)((char*)this)+0xd4, m, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii((char*)&mModel, m, 1, -1); _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); int j = *(int*)((char*)&mVariant) * 0xc; int k = _ZN12MeshCollider8LoadFileER13SharedFilePtr(*(void**)((char*)data_ov015_02114538 + j)); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block((char*)((char*)this)+0x124, k, (char*)((char*)this)+0x2ec, 0x1000, mAngleY, *(void**)((char*)data_ov015_0211453c + j)); - func_020393d4((int*)((char*)&mMeshCollider), (int)&_ZN16MeshColliderBase21UpdatePosWithVelocityERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block((char*)&mMeshCollider, k, (char*)&mClsnMat, 0x1000, mAngleY, *(void**)((char*)data_ov015_0211453c + j)); + func_020393d4((int*)((char*)&(*(u8 *)&mMeshCollider)), (int)&_ZN16MeshColliderBase21UpdatePosWithVelocityERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); int tmp[3]; tmp[0] = 0x1000; tmp[1] = 0; tmp[2] = 0; - func_01ffb0a4((char*)&mMeshCollider); - func_01ffb07c((char*)((char*)this)+0x124, tmp); - func_020396d0((int*)((char*)&mMeshCollider), 0xccd); - *(int*)((char*)&unk_320) = *(int*)((char*)&unk_05c); - *(int*)((char*)&unk_324) = *(int*)((char*)&unk_060); - *(int*)((char*)&unk_328) = *(int*)((char*)&unk_064); + func_01ffb0a4((char*)&(*(u8 *)&mMeshCollider)); + func_01ffb07c((char*)&mMeshCollider, tmp); + func_020396d0((int*)((char*)&(*(u8 *)&mMeshCollider)), 0xccd); + *(int*)((char*)&unk_320) = *(int*)((char*)&mPosX); + *(int*)((char*)&unk_324) = *(int*)((char*)&mPosY); + *(int*)((char*)&unk_328) = *(int*)((char*)&mPosZ); func_ov015_02111fb8(((char*)this), 5); return 1; } diff --git a/src/_ZN14KnockDownPlank16CleanupResourcesEv.cpp b/src/_ZN14KnockDownPlank16CleanupResourcesEv.cpp index 7f5f3ae92..49535a6ef 100644 --- a/src/_ZN14KnockDownPlank16CleanupResourcesEv.cpp +++ b/src/_ZN14KnockDownPlank16CleanupResourcesEv.cpp @@ -10,8 +10,8 @@ extern char data_ov015_02114534[]; int KnockDownPlank::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(*(void **)(data_ov015_02114534 + mVariant * 0xc)))->Release(); ((SharedFilePtr *)(*(void **)(data_ov015_02114538 + mVariant * 0xc)))->Release(); return 1; diff --git a/src/_ZN14MovingBarSmall16CleanupResourcesEv.cpp b/src/_ZN14MovingBarSmall16CleanupResourcesEv.cpp index ec9b141ce..716b8ae94 100644 --- a/src/_ZN14MovingBarSmall16CleanupResourcesEv.cpp +++ b/src/_ZN14MovingBarSmall16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int MovingBarSmall_ModelFile[]; int MovingBarSmall::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(MovingBarSmall_ModelFile))->Release(); ((SharedFilePtr *)(MovingBarSmall_ClsnFile))->Release(); diff --git a/src/_ZN14SquarePathLift13InitResourcesEv.cpp b/src/_ZN14SquarePathLift13InitResourcesEv.cpp index 1597ee2d8..2ecf8edf0 100644 --- a/src/_ZN14SquarePathLift13InitResourcesEv.cpp +++ b/src/_ZN14SquarePathLift13InitResourcesEv.cpp @@ -19,14 +19,14 @@ extern struct SFP data_ov052_021125a0; int SquarePathLift::InitResources() { void* f = _ZN5Model8LoadFileER13SharedFilePtr(data_ov052_021125a0.a); - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this)+0xd4, f, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, f, 1, -1); _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); void* f2 = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov052_021125a0.b); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(((char*)this)+0x124, f2, ((char*)this)+0x2ec, 0x199, mAngleY, data_ov052_021125a0.c); - func_020393d4((int*)((char*)&mMeshCollider), &_ZN16MeshColliderBase22UpdatePosWithTransformERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); - _ZN7PathPtr6FromIDEj(((char*)this)+0x320, mParam&0xff); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(&mMeshCollider, f2, &mClsnMat, 0x199, mAngleY, data_ov052_021125a0.c); + func_020393d4((int*)((char*)&(*(u8 *)&mMeshCollider)), &_ZN16MeshColliderBase22UpdatePosWithTransformERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + _ZN7PathPtr6FromIDEj(((char*)this)+0x320, (*(s32 *)¶m1)&0xff); mPathDir = 1; - mMoveSpeed = 0xa000; + mHorzSpeed = 0xa000; return 1; } diff --git a/src/_ZN14SquarePathLift16CleanupResourcesEv.cpp b/src/_ZN14SquarePathLift16CleanupResourcesEv.cpp index 92f803a70..38cd8a6d6 100644 --- a/src/_ZN14SquarePathLift16CleanupResourcesEv.cpp +++ b/src/_ZN14SquarePathLift16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern SFP data_ov052_021125a0[2]; int SquarePathLift::CleanupResources() { - if(((MeshColliderBase *)((char*)&mMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char*)&mMeshCollider))->Disable(); + if(((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)((void*)data_ov052_021125a0[0].x))->Release(); ((SharedFilePtr *)((void*)data_ov052_021125a0[1].x))->Release(); return 1; diff --git a/src/_ZN14SquarePathLift8BehaviorEv.cpp b/src/_ZN14SquarePathLift8BehaviorEv.cpp index e34f063de..515aa2ddf 100644 --- a/src/_ZN14SquarePathLift8BehaviorEv.cpp +++ b/src/_ZN14SquarePathLift8BehaviorEv.cpp @@ -4,7 +4,6 @@ #include "decl_PathPtr.h" /* recovered: named members + shared header, real C++ method */ #include "SquarePathLift.h" -typedef int Fix12; extern "C" { extern void _ZNK7PathPtr7GetNodeER7Vector3j(void *p, void *out, unsigned idx); extern void Vec3_Sub(void *out, void *a, void *b); @@ -14,7 +13,7 @@ extern void Vec3_MulScalar(void *out, void *v, int s); extern void SubVec3(void *a, void *b, void *c); extern void _ZN8Platform21UpdateModelPosAndRotYEv(void *p); extern void _ZN8Platform19UpdateClsnPosAndRotEv(void *p); -extern int _ZN8Platform13IsClsnInRangeE5Fix12IiES1_(void *p, Fix12 a, int b); +extern int _ZN8Platform13IsClsnInRangeE5Fix12IiES1_(void *p, int a, int b); } struct V3 { int x, y, z; }; @@ -22,7 +21,7 @@ int SquarePathLift::Behavior() { struct V3 prev, node, diff, scaled1, scaled2; int looped, delta, len; - mMoveSpeed = 0xa000; + mHorzSpeed = 0xa000; delta = mNodeIndex - mPathDir; looped = 0; if (_ZNK7PathPtr5LoopsEv((char *)&mPath)) { @@ -37,12 +36,12 @@ int SquarePathLift::Behavior() _ZNK7PathPtr7GetNodeER7Vector3j(((char *)this) + 0x320, &prev, mNodeIndex); Vec3_Sub(&diff, ((char *)this) + 0x5c, &prev); len = LenVec3(&diff); - if (len == 0 || len <= mMoveSpeed) { - Vec3_MulScalar(&scaled1, &diff, _ZN4cstd4fdivEii(mMoveSpeed, len)); + if (len == 0 || len <= mHorzSpeed) { + Vec3_MulScalar(&scaled1, &diff, _ZN4cstd4fdivEii(mHorzSpeed, len)); SubVec3(((char *)this) + 0x5c, &scaled1, ((char *)this) + 0x5c); looped = 1; } else { - Vec3_MulScalar(&scaled2, &diff, _ZN4cstd4fdivEii(mMoveSpeed, len)); + Vec3_MulScalar(&scaled2, &diff, _ZN4cstd4fdivEii(mHorzSpeed, len)); SubVec3(((char *)this) + 0x5c, &scaled2, ((char *)this) + 0x5c); } if (looped) { diff --git a/src/_ZN14UnchainedChompD0Ev.cpp b/src/_ZN14UnchainedChompD0Ev.cpp index 42a0efe32..cd1704cd7 100644 --- a/src/_ZN14UnchainedChompD0Ev.cpp +++ b/src/_ZN14UnchainedChompD0Ev.cpp @@ -11,15 +11,15 @@ int _ZN25MovingCylinderClsnWithPosD1Ev(void*); int _ZN5EnemyD2Ev(void*); int _ZN6Memory10DeallocateEPvP4Heap(void*, void*); extern int _ZTV14UnchainedChomp[]; -extern void func_02011508(); -extern void func_020072c0(); +extern void _ZN8Vector3sD1Ev(); +extern void _ZN7Vector3D1Ev(); extern void _ZN5ModelD1Ev(); extern int data_020a0eac[]; void* _ZN14UnchainedChompD0Ev(struct UnchainedChomp *self) { *(int**)((char*)self) = _ZTV14UnchainedChomp; - __destroy_arr(((char*)self)+0x768, 6, 6, (void*)func_02011508); - __destroy_arr(((char*)self)+0x720, 6, 0xc, (void*)func_020072c0); - __destroy_arr(((char*)self)+0x6d8, 6, 0xc, (void*)func_020072c0); + __destroy_arr(((char*)self)+0x768, 6, 6, (void*)_ZN8Vector3sD1Ev); + __destroy_arr(((char*)self)+0x720, 6, 0xc, (void*)_ZN7Vector3D1Ev); + __destroy_arr(((char*)self)+0x6d8, 6, 0xc, (void*)_ZN7Vector3D1Ev); _ZN11ShadowModelD1Ev((char*)&self->mShadowModel); __destroy_arr(((char*)self)+0x550, 6, 0x28, (void*)_ZN11ShadowModelD1Ev); __destroy_arr(((char*)self)+0x370, 6, 0x50, (void*)_ZN5ModelD1Ev); diff --git a/src/_ZN14UnchainedChompD1Ev.cpp b/src/_ZN14UnchainedChompD1Ev.cpp index 58fe310e0..8eff93df3 100644 --- a/src/_ZN14UnchainedChompD1Ev.cpp +++ b/src/_ZN14UnchainedChompD1Ev.cpp @@ -12,16 +12,16 @@ extern "C" void _ZN25MovingCylinderClsnWithPosD1Ev(void*); extern "C" int _ZN5EnemyD2Ev(int* x); extern int _ZTV14UnchainedChomp; -extern "C" void func_02011508(void); -extern "C" void func_020072c0(void); +extern "C" void _ZN8Vector3sD1Ev(void); +extern "C" void _ZN7Vector3D1Ev(void); extern "C" void* _ZN14UnchainedChompD1Ev(char* thiz) { char* c = thiz; *(void**)c = &_ZTV14UnchainedChomp; - __destroy_arr(c + 0x768, 6, 6, (void*)&func_02011508); - __destroy_arr(c + 0x720, 6, 0xc, (void*)&func_020072c0); - __destroy_arr(c + 0x6d8, 6, 0xc, (void*)&func_020072c0); + __destroy_arr(c + 0x768, 6, 6, (void*)&_ZN8Vector3sD1Ev); + __destroy_arr(c + 0x720, 6, 0xc, (void*)&_ZN7Vector3D1Ev); + __destroy_arr(c + 0x6d8, 6, 0xc, (void*)&_ZN7Vector3D1Ev); _ZN11ShadowModelD1Ev(c + 0x640); __destroy_arr(c + 0x550, 6, 0x28, (void*)&_ZN11ShadowModelD1Ev); __destroy_arr(c + 0x370, 6, 0x50, (void*)&_ZN5ModelD1Ev); diff --git a/src/_ZN15ChainChompFence13InitResourcesEv.cpp b/src/_ZN15ChainChompFence13InitResourcesEv.cpp index 646aef474..1f3285356 100644 --- a/src/_ZN15ChainChompFence13InitResourcesEv.cpp +++ b/src/_ZN15ChainChompFence13InitResourcesEv.cpp @@ -23,10 +23,10 @@ extern int data_ov014_021149c0[]; int ChainChompFence::InitResources() { int m = _ZN5Model8LoadFileER13SharedFilePtr(data_ov014_021149c0); - _ZN9ModelBase7SetFileEP8BMD_Fileii((char*)((char*)this)+0xd4, m, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii((char*)&mModel, m, 1, -1); _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); int k = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov014_021149b8); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block((char*)((char*)this)+0x124, k, (char*)((char*)this)+0x2ec, 0x1000, unk_08e, (void*)data_ov014_02114558); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block((char*)&mMeshCollider, k, (char*)&mClsnMat, 0x1000, mAngleY, (void*)data_ov014_02114558); return 1; } diff --git a/src/_ZN15ChainChompFence16CleanupResourcesEv.cpp b/src/_ZN15ChainChompFence16CleanupResourcesEv.cpp index 3fee05e1a..843334d94 100644 --- a/src/_ZN15ChainChompFence16CleanupResourcesEv.cpp +++ b/src/_ZN15ChainChompFence16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int data_ov014_021149c0[]; int ChainChompFence::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMovingMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMovingMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(data_ov014_021149c0))->Release(); ((SharedFilePtr *)(data_ov014_021149b8))->Release(); diff --git a/src/_ZN15FireSeaElevator13InitResourcesEv.cpp b/src/_ZN15FireSeaElevator13InitResourcesEv.cpp index 75d38988a..889bfa2fe 100644 --- a/src/_ZN15FireSeaElevator13InitResourcesEv.cpp +++ b/src/_ZN15FireSeaElevator13InitResourcesEv.cpp @@ -18,7 +18,7 @@ int FireSeaElevator::InitResources() { void* m = _ZN5Model8LoadFileER13SharedFilePtr(data_ov045_021131b0); _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this) + 0xd4, m, 1, -1); - if (unk_008 != 0xffff) { + if ((*(s32 *)¶m1) != 0xffff) { int* p = (int*)(((int)((char*)this) + 0x60)); *p -= 0x12c000; } @@ -26,7 +26,7 @@ int FireSeaElevator::InitResources() _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); void* mc = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov045_021131a8); _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - ((char*)this) + 0x124, mc, ((char*)this) + 0x2ec, 0x199, unk_08e, data_ov045_02112510); + ((char*)this) + 0x124, mc, ((char*)this) + 0x2ec, 0x199, mAngleY, data_ov045_02112510); _ZN18MovingCylinderClsn4InitEP5Actor5Fix12IiES3_jj( ((char*)this) + 0x320, ((char*)this), 0x35555, 0x258000, 0x280000c, 0); return 1; diff --git a/src/_ZN15FireSeaElevator16CleanupResourcesEv.cpp b/src/_ZN15FireSeaElevator16CleanupResourcesEv.cpp index b042f9f03..eda3a5d5e 100644 --- a/src/_ZN15FireSeaElevator16CleanupResourcesEv.cpp +++ b/src/_ZN15FireSeaElevator16CleanupResourcesEv.cpp @@ -10,7 +10,7 @@ extern int data_ov045_021131b0[]; int FireSeaElevator::CleanupResources() { - ((MeshColliderBase *)((char *)&mMovingMeshCollider))->Disable(); + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(data_ov045_021131b0))->Release(); ((SharedFilePtr *)(data_ov045_021131a8))->Release(); return 1; diff --git a/src/_ZN15FireSeaElevator8BehaviorEv.cpp b/src/_ZN15FireSeaElevator8BehaviorEv.cpp index 20764c9e6..c97e2f557 100644 --- a/src/_ZN15FireSeaElevator8BehaviorEv.cpp +++ b/src/_ZN15FireSeaElevator8BehaviorEv.cpp @@ -2,12 +2,11 @@ // @symbol _ZN15FireSeaElevator8BehaviorEv /* recovered: named members + shared header, real C++ method */ #include "FireSeaElevator.h" -typedef int Fix12; extern "C" { extern void _ZN12CylinderClsn5ClearEv(void *self); extern void _ZN12CylinderClsn6UpdateEv(void *self); extern void _ZN8Platform21UpdateModelPosAndRotYEv(void *self); -extern int _ZN8Platform21IsClsnInRangeOnScreenE5Fix12IiES1_(void *self, Fix12 a, int b); +extern int _ZN8Platform21IsClsnInRangeOnScreenE5Fix12IiES1_(void *self, int a, int b); extern void _ZN8Platform19UpdateClsnPosAndRotEv(void *self); } extern short data_02082214[]; @@ -16,7 +15,7 @@ int FireSeaElevator::Behavior() { _ZN12CylinderClsn5ClearEv((char *)&mMovingCylinderClsn); _ZN12CylinderClsn6UpdateEv((char *)&mMovingCylinderClsn); - if (unk_008 != 0xffff) { + if ((*(s32 *)¶m1) != 0xffff) { int idx = unk_354 >> 4; int s = *(short*)((char*)data_02082214 + (idx << 2)); *(int*)(((int)((char *)this) + 0x60)) = diff --git a/src/_ZN15RotatingFirebar13InitResourcesEv.cpp b/src/_ZN15RotatingFirebar13InitResourcesEv.cpp index 93d353dd5..8cbc562db 100644 --- a/src/_ZN15RotatingFirebar13InitResourcesEv.cpp +++ b/src/_ZN15RotatingFirebar13InitResourcesEv.cpp @@ -34,7 +34,7 @@ int RotatingFirebar::InitResources() _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( ((char*)this) + 0x124, _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov064_0211adbc[1]), - ((char*)this) + 0x2ec, 0x199, unk_08e, data_ov064_0211adbc[2]); + ((char*)this) + 0x2ec, 0x199, mAngleY, data_ov064_0211adbc[2]); func_020393d4((int*)((char*)&mMeshCollider), (int)&_ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); return 1; diff --git a/src/_ZN15RotatingFirebar8BehaviorEv.cpp b/src/_ZN15RotatingFirebar8BehaviorEv.cpp index a29655da6..81dd9e098 100644 --- a/src/_ZN15RotatingFirebar8BehaviorEv.cpp +++ b/src/_ZN15RotatingFirebar8BehaviorEv.cpp @@ -43,7 +43,7 @@ int RotatingFirebar::Behavior() *(s16*)AT(((char*)this), 0x8e) = *(s16*)AT(((char*)this), 0x8e) - 0x100; - b = ((unk_0b0 & 8) != 0) ? 1 : 0; + b = ((mFlags & 8) != 0) ? 1 : 0; if (b) { if (((MeshColliderBase *)((char*)&mMeshCollider))->IsEnabled() != 0) { ((MeshColliderBase *)((char*)&mMeshCollider))->Disable(); @@ -52,7 +52,7 @@ int RotatingFirebar::Behavior() } _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); - Matrix4x3_FromRotationY(data_020a0e68, unk_08e); + Matrix4x3_FromRotationY(data_020a0e68, mAngleY); w = ((char*)this); cyl = ((char*)this) + 0x360; diff --git a/src/_ZN15TtcRotatingGear13InitResourcesEv.cpp b/src/_ZN15TtcRotatingGear13InitResourcesEv.cpp index cc31276b4..e20914e3d 100644 --- a/src/_ZN15TtcRotatingGear13InitResourcesEv.cpp +++ b/src/_ZN15TtcRotatingGear13InitResourcesEv.cpp @@ -4,14 +4,13 @@ #include "decl_common.h" /* recovered: named members + shared header, real C++ method */ #include "TtcRotatingGear.h" -typedef int Fix12; extern void* _ZN5Model8LoadFileER13SharedFilePtr(void*); extern void _ZN9ModelBase7SetFileEP8BMD_Fileii(void*, void*, int, int); extern void _ZN8Platform21UpdateModelPosAndRotYEv(void*); extern void _ZN8Platform19UpdateClsnPosAndRotEv(void*); extern void* _ZN12MeshCollider8LoadFileER13SharedFilePtr(void*); extern void _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - void*, void*, void*, Fix12, short, void*); + void*, void*, void*, int, short, void*); extern unsigned char data_0209f2c0[]; extern char data_ov065_0211c0d4[]; @@ -38,7 +37,7 @@ int TtcRotatingGear::InitResources() b = mMoveDir; unk_32c = *(unsigned short*)(data_ov065_0211c0d4 + (ip << 4) + (b << 3)); b = mMoveDir; - unk_0a8 = *(int*)(data_ov065_0211c0d0 + (ip << 4) + (b << 3)); - unk_0a0 = -0x3c000; + mVertSpeed = *(int*)(data_ov065_0211c0d0 + (ip << 4) + (b << 3)); + mTerminalVelocity = -0x3c000; return 1; } diff --git a/src/_ZN15TtcRotatingGear16CleanupResourcesEv.cpp b/src/_ZN15TtcRotatingGear16CleanupResourcesEv.cpp index 554193451..d77a98949 100644 --- a/src/_ZN15TtcRotatingGear16CleanupResourcesEv.cpp +++ b/src/_ZN15TtcRotatingGear16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int TtcRotatingGear_ModelFile[]; int TtcRotatingGear::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(TtcRotatingGear_ModelFile))->Release(); ((SharedFilePtr *)(TtcRotatingGear_ClsnFile))->Release(); diff --git a/src/_ZN16RotatingCogSmall13InitResourcesEv.cpp b/src/_ZN16RotatingCogSmall13InitResourcesEv.cpp index 50ad2869d..142676094 100644 --- a/src/_ZN16RotatingCogSmall13InitResourcesEv.cpp +++ b/src/_ZN16RotatingCogSmall13InitResourcesEv.cpp @@ -29,26 +29,26 @@ int RotatingCogSmall::InitResources() { int b; - b = (int)(unk_00c == 0x77); + b = (int)(actorID == 0x77); if (b != 0) { - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char *)this) + 0xd4, + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, _ZN5Model8LoadFileER13SharedFilePtr(data_ov035_02112c78), 1, -1); _ZN8Platform21UpdateModelPosAndRotYEv(((char *)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char *)this)); _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - ((char *)this) + 0x124, + &mMeshCollider, _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov035_02112c68), - ((char *)this) + 0x2ec, 0x1000, unk_08e, data_ov035_021121d8); - func_020396c0(((char *)this) + 0x124, 0); - func_020393d4(((char *)this) + 0x124, &_ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + &mClsnMat, 0x1000, mAngleY, data_ov035_021121d8); + func_020396c0(&mMeshCollider, 0); + func_020393d4(&mMeshCollider, &_ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); mRotationState = 0; } else { - b = (int)(unk_00c == 0x79); + b = (int)(actorID == 0x79); if (b != 0) { - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char *)this) + 0xd4, + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, _ZN5Model8LoadFileER13SharedFilePtr(data_ov035_02112c70), 1, -1); } else { - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char *)this) + 0xd4, + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, _ZN5Model8LoadFileER13SharedFilePtr(data_ov035_02112c60), 1, -1); } _ZN8Platform21UpdateModelPosAndRotYEv(((char *)this)); diff --git a/src/_ZN16RotatingCogSmall16CleanupResourcesEv.cpp b/src/_ZN16RotatingCogSmall16CleanupResourcesEv.cpp index ca74a072e..d85d79ffd 100644 --- a/src/_ZN16RotatingCogSmall16CleanupResourcesEv.cpp +++ b/src/_ZN16RotatingCogSmall16CleanupResourcesEv.cpp @@ -15,12 +15,12 @@ extern char data_ov035_02112c60[]; int RotatingCogSmall::CleanupResources() { if(mRotationState==0){ - if(((MeshColliderBase *)((char *)&mMovingMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMovingMeshCollider))->Disable(); + if(((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(data_ov035_02112c78))->Release(); ((SharedFilePtr *)(data_ov035_02112c68))->Release(); } else { - int on = (unk_00c==0x79); + int on = (actorID==0x79); if(on) ((SharedFilePtr *)(data_ov035_02112c70))->Release(); else diff --git a/src/_ZN16RotatingCogSmall8BehaviorEv.cpp b/src/_ZN16RotatingCogSmall8BehaviorEv.cpp index eb9694fe2..0d613d0ec 100644 --- a/src/_ZN16RotatingCogSmall8BehaviorEv.cpp +++ b/src/_ZN16RotatingCogSmall8BehaviorEv.cpp @@ -24,7 +24,7 @@ int RotatingCogSmall::Behavior() return 1; } - if (_Z14ApproachLinearRsss((short*)((char*)&unk_08e), unk_322, 0xc8) != 0 && + if (_Z14ApproachLinearRsss((short*)((char*)&mAngleY), unk_322, 0xc8) != 0 && DecIfAbove0_Short((unsigned short*)((char*)&unk_31e)) == 0) { short* p = (short*)(((int)((char*)this) + 0x322)); *p = *p + unk_324; diff --git a/src/_ZN17BowserPuzzlePiece13InitResourcesEv.cpp b/src/_ZN17BowserPuzzlePiece13InitResourcesEv.cpp index 5cc9921e8..01b584cfd 100644 --- a/src/_ZN17BowserPuzzlePiece13InitResourcesEv.cpp +++ b/src/_ZN17BowserPuzzlePiece13InitResourcesEv.cpp @@ -4,12 +4,12 @@ #include "decl_common.h" /* recovered: named members + shared header, real C++ method */ #include "BowserPuzzlePiece.h" +#include "MovingCylinderClsn.h" typedef int Fix12i; struct SharedFilePtr; struct Actor; namespace Model { void LoadFile(SharedFilePtr& f); } extern "C" int IsStarCollected(int r0, int r1); -struct MovingCylinderClsn { void Init(Actor* a, Fix12i b, int c, unsigned int d, unsigned int e); }; /* Signature deliberately copied from the local declaration above: the ROM name carries by-value class parameters (e.g. Fix12), which mwccarm passes differently at the call site, so declaring the true @@ -22,17 +22,17 @@ extern SharedFilePtr data_ov002_0210d9a8; extern signed char data_0209f2f8; extern unsigned char data_0209f220; -int BowserPuzzlePiece::InitResources() +s32 BowserPuzzlePiece::InitResources() { Model::LoadFile(data_ov002_0210da10); Model::LoadFile(data_ov002_0210d9a8); - unk_314 = (unk_008 >> 0xc) & 0xf; - unk_318 = unk_008 & 1; - if ((unk_008 & 0xf) > 1) unk_318 = 0; + unk_314 = (param1 >> 0xc) & 0xf; + unk_318 = param1 & 1; + if ((param1 & 0xf) > 1) unk_318 = 0; if (data_0209f2f8 == 8 && (data_0209f220 == 1 || IsStarCollected(SublevelToLevel(8), 1) == 0)) { return 0; } - _ZN18MovingCylinderClsn4InitEP5Actor5Fix12IiES3_jj((MovingCylinderClsn*)((char*)&mMovingCylinderClsn), (Actor*)((char*)this), 0xc8000, 0x190000, 0x800004, 0); + _ZN18MovingCylinderClsn4InitEP5Actor5Fix12IiES3_jj((MovingCylinderClsn*)((char*)&(*(u8 *)&mMovingCylinderClsn)), (Actor*)((char*)this), 0xc8000, 0x190000, 0x800004, 0); func_ov064_0211982c(((char*)this), &data_ov064_0211c934); return 1; } diff --git a/src/_ZN17BowserPuzzlePiece16CleanupResourcesEv.cpp b/src/_ZN17BowserPuzzlePiece16CleanupResourcesEv.cpp index 00370f66f..b4e2cc302 100644 --- a/src/_ZN17BowserPuzzlePiece16CleanupResourcesEv.cpp +++ b/src/_ZN17BowserPuzzlePiece16CleanupResourcesEv.cpp @@ -15,7 +15,7 @@ extern char data_ov002_0210da10; extern char data_ov002_0210d9a8; -int BowserPuzzlePiece::CleanupResources() +s32 BowserPuzzlePiece::CleanupResources() { ((SharedFilePtr *)(&data_ov002_0210da10))->Release(); ((SharedFilePtr *)(&data_ov002_0210d9a8))->Release(); diff --git a/src/_ZN17BowserPuzzlePiece6RenderEv.cpp b/src/_ZN17BowserPuzzlePiece6RenderEv.cpp index f9faa6bb8..cfeb68672 100644 --- a/src/_ZN17BowserPuzzlePiece6RenderEv.cpp +++ b/src/_ZN17BowserPuzzlePiece6RenderEv.cpp @@ -8,7 +8,7 @@ */ #include "BowserPuzzlePiece.h" -int BowserPuzzlePiece::Render() +s32 BowserPuzzlePiece::Render() { return 1; } diff --git a/src/_ZN17BowserPuzzlePiece8BehaviorEv.cpp b/src/_ZN17BowserPuzzlePiece8BehaviorEv.cpp index 8b686a00b..d02e0793b 100644 --- a/src/_ZN17BowserPuzzlePiece8BehaviorEv.cpp +++ b/src/_ZN17BowserPuzzlePiece8BehaviorEv.cpp @@ -14,15 +14,15 @@ struct C { Obj* obj; }; -int BowserPuzzlePiece::Behavior() +s32 BowserPuzzlePiece::Behavior() { - DecIfAbove0_Short((unsigned short*)((char*)&unk_100)); + DecIfAbove0_Short((unsigned short*)((char*)&(*(u8 *)&unk_100))); if(((C*)this)->obj->pmf){ (((C*)this)->*(((C*)this)->obj->pmf))(); } - *(short*)((char*)&unk_08c) = *(short*)((char*)&unk_092); - *(short*)((char*)&unk_08e) = *(short*)((char*)&unk_094); - *(short*)((char*)&unk_090) = *(short*)((char*)&unk_096); + *(short*)((char*)&mAngleX) = *(short*)((char*)&mPrevAngleX); + *(short*)((char*)&mAngleY) = *(short*)((char*)&mPrevAngleY); + *(short*)((char*)&mAngleZ) = *(short*)((char*)&mPrevAngleZ); func_ov064_0211987c(((C*)this)); return 1; } diff --git a/src/_ZN17SlidingPlatformWf16CleanupResourcesEv.cpp b/src/_ZN17SlidingPlatformWf16CleanupResourcesEv.cpp index f24563c9e..29e50ac6c 100644 --- a/src/_ZN17SlidingPlatformWf16CleanupResourcesEv.cpp +++ b/src/_ZN17SlidingPlatformWf16CleanupResourcesEv.cpp @@ -9,8 +9,8 @@ int SlidingPlatformWf::CleanupResources() { - if(((MeshColliderBase *)((char *)&mMovingMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMovingMeshCollider))->Disable(); + if(((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(*(void**)(data_ov091_02135024 + (unsigned char)((char *)this)[0x322]*0xc)))->Release(); ((SharedFilePtr *)(*(void**)(data_ov091_02135028 + (unsigned char)((char *)this)[0x322]*0xc)))->Release(); return 1; diff --git a/src/_ZN19FloatingFloorLllBig16CleanupResourcesEv.cpp b/src/_ZN19FloatingFloorLllBig16CleanupResourcesEv.cpp index d8cb88524..c5ef03701 100644 --- a/src/_ZN19FloatingFloorLllBig16CleanupResourcesEv.cpp +++ b/src/_ZN19FloatingFloorLllBig16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int FloatingFloorLllBig_ModelFile[]; int FloatingFloorLllBig::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(FloatingFloorLllBig_ModelFile))->Release(); ((SharedFilePtr *)(FloatingFloorLllBig_ClsnFile))->Release(); diff --git a/src/_ZN19FloatingFloorLllBigD1Ev.cpp b/src/_ZN19FloatingFloorLllBigD1Ev.cpp index d89c13a2b..d2640a117 100644 --- a/src/_ZN19FloatingFloorLllBigD1Ev.cpp +++ b/src/_ZN19FloatingFloorLllBigD1Ev.cpp @@ -2,12 +2,11 @@ // @symbol _ZN19FloatingFloorLllBigD1Ev /* recovered: real C++ destructor -- the compiler emits the whole body * - * Two vtable stores and three destructor calls, all of them consequences of + * Two vtable stores and three destructor calls, every one a consequence of * `struct FloatingFloorLllBig : Platform`: its own vptr, then Platform's -- inlined, * because Platform's destructor is defined in its class body -- then - * Platform's Model and MovingMeshCollider, then Actor. - * - * This class adds no member with a destructor, so it contributes nothing. + * Platform's Model and MovingMeshCollider, then Actor. This class adds no + * member with a destructor of its own. */ #include "FloatingFloorLllBig.h" diff --git a/src/_ZN19RotatingPlatformLll13InitResourcesEv.cpp b/src/_ZN19RotatingPlatformLll13InitResourcesEv.cpp index d4595e704..4489bc39d 100644 --- a/src/_ZN19RotatingPlatformLll13InitResourcesEv.cpp +++ b/src/_ZN19RotatingPlatformLll13InitResourcesEv.cpp @@ -4,14 +4,13 @@ #include "decl_common.h" /* recovered: named members + shared header, real C++ method */ #include "RotatingPlatformLll.h" -typedef int Fix12; extern "C" { extern void* _ZN5Model8LoadFileER13SharedFilePtr(void*); extern int _ZN9ModelBase7SetFileEP8BMD_Fileii(void*, void*, int, int); extern int _ZN8Platform21UpdateModelPosAndRotYEv(void*); extern int _ZN8Platform19UpdateClsnPosAndRotEv(void*); extern void* _ZN12MeshCollider8LoadFileER13SharedFilePtr(void*); -extern int _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(void*, void*, void*, Fix12, short, void*); +extern int _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(void*, void*, void*, int, short, void*); extern int func_020393d4(void*, void*); extern int func_020393c4(void*, void*); } @@ -25,13 +24,13 @@ int RotatingPlatformLll::InitResources() void* mdl; void* kcl; mdl = _ZN5Model8LoadFileER13SharedFilePtr(data_ov022_02114558); - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this)+0xd4, mdl, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, mdl, 1, -1); _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); kcl = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov022_02114550); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(((char*)this)+0x124, kcl, ((char*)this)+0x2ec, 0x199, mAngleY, data_ov064_0211bb0c); - func_020393d4(((char*)this)+0x124, &_ZN16MeshColliderBase21UpdatePosWithVelocityERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); - func_020393c4(((char*)this)+0x124, &func_ov022_0211193c); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(&mMeshCollider, kcl, &mClsnMat, 0x199, mAngleY, data_ov064_0211bb0c); + func_020393d4(&mMeshCollider, &_ZN16MeshColliderBase21UpdatePosWithVelocityERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + func_020393c4(&mMeshCollider, &func_ov022_0211193c); unk_320 = mPosY; return 1; } diff --git a/src/_ZN19RotatingPlatformLll16CleanupResourcesEv.cpp b/src/_ZN19RotatingPlatformLll16CleanupResourcesEv.cpp index 9dad5d7ae..115fd65c5 100644 --- a/src/_ZN19RotatingPlatformLll16CleanupResourcesEv.cpp +++ b/src/_ZN19RotatingPlatformLll16CleanupResourcesEv.cpp @@ -10,8 +10,8 @@ extern int data_ov022_02114558[]; int RotatingPlatformLll::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(data_ov022_02114558))->Release(); ((SharedFilePtr *)(data_ov022_02114550))->Release(); diff --git a/src/_ZN19RotatingPlatformLll8BehaviorEv.cpp b/src/_ZN19RotatingPlatformLll8BehaviorEv.cpp index 92b7228f6..9fddc56f4 100644 --- a/src/_ZN19RotatingPlatformLll8BehaviorEv.cpp +++ b/src/_ZN19RotatingPlatformLll8BehaviorEv.cpp @@ -8,7 +8,7 @@ extern void func_020393a4(int* p, int v); int RotatingPlatformLll::Behavior() { - func_020393a4((int*)((char*)&mMeshCollider), 0x150000); + func_020393a4((int*)((char*)&(*(u8 *)&mMeshCollider)), 0x150000); if (unk_324) { int* py = (int*)(((int)((char*)this) + 0x60)); *py = *py - 0x2000; diff --git a/src/_ZN19RotatingPlatformWdw13InitResourcesEv.cpp b/src/_ZN19RotatingPlatformWdw13InitResourcesEv.cpp index f5fe9a5dc..b8955706a 100644 --- a/src/_ZN19RotatingPlatformWdw13InitResourcesEv.cpp +++ b/src/_ZN19RotatingPlatformWdw13InitResourcesEv.cpp @@ -27,11 +27,11 @@ int RotatingPlatformWdw::InitResources() void *k; m = _ZN5Model8LoadFileER13SharedFilePtr(data_ov029_021142fc); - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char *)this) + 0xd4, m, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, m, 1, -1); _ZN18TextureTransformer7PrepareER8BMD_FileR8BTA_File(data_ov029_021142fc[1], &data_ov029_02112fb8); _ZN18TextureTransformer7SetFileER8BTA_Filei5Fix12IiEj(((char *)this) + 0x320, &data_ov029_02112fb8, 0, 0x1000, 0); - unk_338 = (u8)(mParam & 1); + unk_338 = (u8)((*(s32 *)¶m1) & 1); if (unk_338 == 0) { unsigned int idx = data_0209f2c0[0]; if (idx >= 3) idx = 2; @@ -45,8 +45,8 @@ int RotatingPlatformWdw::InitResources() k = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov029_02114304); _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - ((char *)this) + 0x124, k, ((char *)this) + 0x2ec, 0x1000, mAngleY, &data_ov029_02112fec); - ((MeshColliderBase *)(((char *)this) + 0x124))->Enable((Actor *)(((char *)this))); + &mMeshCollider, k, &mClsnMat, 0x1000, mAngleY, &data_ov029_02112fec); + ((MeshColliderBase *)(&mMeshCollider))->Enable((Actor *)(((char *)this))); unk_340 = (u8)mAreaId; mAreaId = -1; diff --git a/src/_ZN19RotatingPlatformWdw16CleanupResourcesEv.cpp b/src/_ZN19RotatingPlatformWdw16CleanupResourcesEv.cpp index 284adf21a..d267f6443 100644 --- a/src/_ZN19RotatingPlatformWdw16CleanupResourcesEv.cpp +++ b/src/_ZN19RotatingPlatformWdw16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int RotatingPlatformWdw_ModelFile[]; int RotatingPlatformWdw::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(RotatingPlatformWdw_ModelFile))->Release(); ((SharedFilePtr *)(RotatingPlatformWdw_ClsnFile))->Release(); diff --git a/src/_ZN19RotatingPlatformWdw8BehaviorEv.cpp b/src/_ZN19RotatingPlatformWdw8BehaviorEv.cpp index 404658a93..61e2a0b37 100644 --- a/src/_ZN19RotatingPlatformWdw8BehaviorEv.cpp +++ b/src/_ZN19RotatingPlatformWdw8BehaviorEv.cpp @@ -25,11 +25,11 @@ int RotatingPlatformWdw::Behavior() /* area id at 0x340: ROM does add r0,r4,#0x300; ldrsb r0,[r0,#0x40] */ if (IsAreaShowing(*(s8 *)((u8 *)(((int)((u8 *)this) + 0x300)) + 0x40)) == 0) { mAreaId = *(s8 *)((u8 *)(((unsigned)((u8 *)this) + 0x300)) + 0x40); - if (((MeshColliderBase *)((u8 *)&mMeshCollider))->IsEnabled() != 0) { - ((MeshColliderBase *)((u8 *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((u8 *)&(*(u8 *)&mMeshCollider)))->IsEnabled() != 0) { + ((MeshColliderBase *)((u8 *)&(*(u8 *)&mMeshCollider)))->Disable(); } } else { - if (((MeshColliderBase *)((u8 *)&mMeshCollider))->IsEnabled() == 0) { + if (((MeshColliderBase *)((u8 *)&(*(u8 *)&mMeshCollider)))->IsEnabled() == 0) { ((MeshColliderBase *)(((u8 *)this) + 0x124))->Enable((Actor *)(((u8 *)this))); } } @@ -65,7 +65,7 @@ int RotatingPlatformWdw::Behavior() data_0209f32c = unk_344; func_ov029_021122b4(((u8 *)this)); func_ov029_02112250(((u8 *)this)); - unk_32c = 0x1000; - _ZN9Animation7AdvanceEv((u8 *)&mTextureTransformer); + (*(s32 *)((char *)&mTextureTransformer + 0xc)) = 0x1000; + _ZN9Animation7AdvanceEv((u8 *)&(*(u8 *)&mTextureTransformer)); return 1; } diff --git a/src/_ZN5EnemyD0Ev.c b/src/_ZN5EnemyD0Ev.c deleted file mode 100644 index cc732468e..000000000 --- a/src/_ZN5EnemyD0Ev.c +++ /dev/null @@ -1,28 +0,0 @@ -// @symbol _ZN5EnemyD0Ev -/* recovered: named members + shared header, declarations from a shared header */ -#include "decl_Actor.h" -#include "decl_common.h" -/* This file does NOT include Enemy.h, and that is deliberate. - * - * Enemy.h now declares a virtual destructor, so in C++ Enemy carries a vptr at - * 0x00 that a C translation unit does not model -- the two languages would - * disagree about every field offset by four bytes. This file was Enemy.h's - * only C reader, and it never touched a field: it uses t[0] and passes t - * along, nothing more. Dropping the include removes the disagreement without - * pretending the file has been migrated. - * - * Renaming it .cpp would be the other way to remove the C reader, and it is - * the WRONG way: D0 is the deleting destructor, which is compiler-generated - * and cannot be written by hand, so the file would stay hand-spelt and merely - * change extension -- `cpp_still_handspelled` 155 -> 156. That is the "renamed, - * never migrated" debt of issue #821, and the ratchet correctly rejects it. - */ -extern void* data_020a0eac; -extern int data_ov002_021081e4[]; -int *_ZN5EnemyD0Ev(int *t) -{ - t[0] = (int)data_ov002_021081e4; - _ZN5ActorD2Ev(t); - _ZN6Memory10DeallocateEPvP4Heap(t, data_020a0eac); - return t; -} diff --git a/src/_ZN5EnemyD0Ev.cpp b/src/_ZN5EnemyD0Ev.cpp new file mode 100644 index 000000000..5574dc11a --- /dev/null +++ b/src/_ZN5EnemyD0Ev.cpp @@ -0,0 +1,18 @@ +//cpp +// @symbol _ZN5EnemyD0Ev +/* recovered: real C++ deleting destructor -- the compiler emits the whole body + * + * D0 is the DELETING destructor: destroy through this class and its bases -- + * which is why more than one vptr store appears -- then return the object to + * its heap. Nobody writes that; declaring `~Enemy()` is enough, because mwcc + * emits D2, D0 and D1 together and objisolate keeps the one this file is bound + * to. + * + * The deallocation is an inline operator delete, which is why nothing below + * mentions a heap. + */ +#include "Enemy.h" + +Enemy::~Enemy() +{ +} diff --git a/src/_ZN5EnemyD1Ev.c b/src/_ZN5EnemyD1Ev.c deleted file mode 100644 index a09da167c..000000000 --- a/src/_ZN5EnemyD1Ev.c +++ /dev/null @@ -1,22 +0,0 @@ -/* Enemy::~Enemy() at 0x020aed74 (ov002) -- complete-object destructor (D1). - * Sets the vptr to Enemy's vtable, then delegates to the Actor base-object - * destructor and returns this. Enemy (0x110) : Actor (0xd4) : ActorBase. - * - * It occupies slot 16 of dEnemyBase_c's vtable, and a D2 is never in a vtable; - * it was named D2 until notes/dtor-variant-audit.md. The Actor call below is a - * genuine D2 -- that is what a D1 delegates to. - */ - -extern void *data_ov002_021081e4; /* Enemy vtable (wildcard reloc) */ -extern void *_ZN5ActorD2Ev(void *self); /* Actor::~Actor (already named) */ - -struct Enemy { - void *vtable; -}; - -void *_ZN5EnemyD1Ev(struct Enemy *self) -{ - self->vtable = &data_ov002_021081e4; - _ZN5ActorD2Ev(self); - return self; -} diff --git a/src/_ZN5EnemyD1Ev.cpp b/src/_ZN5EnemyD1Ev.cpp new file mode 100644 index 000000000..e8c818a46 --- /dev/null +++ b/src/_ZN5EnemyD1Ev.cpp @@ -0,0 +1,22 @@ +//cpp +// @symbol _ZN5EnemyD1Ev +/* recovered: real C++ destructor -- the compiler emits the whole body + * + * Store this class's vtable over the one Actor's constructor left, then run + * the Actor subobject destructor. Both follow from `struct Enemy : Actor` and + * `virtual ~Enemy()`; Enemy owns nothing with a destructor of its own. + * + * This needed the vtable to have a NAME. A real destructor stores _ZTV5Enemy, + * and the tree only knew 0x021081e4 as data_ov002_021081e4, so the link failed + * on an undefined symbol while the bytes matched perfectly. The alias is now in + * ov002's symbols.txt -- see the note there. + * + * The destructor stays OUT-OF-LINE, unlike Platform's: the 51 classes derived + * from Enemy call _ZN5EnemyD2Ev rather than inlining its vptr store, so a + * visible body would make each of them emit code the ROM does not have. + */ +#include "Enemy.h" + +Enemy::~Enemy() +{ +} diff --git a/src/_ZN5Shark13InitResourcesEv.cpp b/src/_ZN5Shark13InitResourcesEv.cpp index 2bd49a11f..04b2a6b31 100644 --- a/src/_ZN5Shark13InitResourcesEv.cpp +++ b/src/_ZN5Shark13InitResourcesEv.cpp @@ -5,6 +5,7 @@ #include "decl_common.h" /* recovered: named members + shared header, real C++ method */ #include "Shark.h" +#include "PathPtr.h" extern "C" { extern void* _ZN5Model8LoadFileER13SharedFilePtr(void* f); extern void _ZN9ModelBase7SetFileEP8BMD_Fileii(void* thiz, void* file, int a, int b); @@ -17,7 +18,6 @@ extern void _ZNK7PathPtr7GetNodeER7Vector3j(void* thiz, void* out, unsigned int extern char data_ov090_021345ac[]; -struct PathPtr { int a; int b; }; } int Shark::InitResources() @@ -27,12 +27,12 @@ int Shark::InitResources() _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this) + 0x30c, _ZN5Model8LoadFileER13SharedFilePtr(data_ov090_021345a4), 1, -1); _ZN9Animation8LoadFileER13SharedFilePtr(data_ov090_021345ac); - mPathID = mParam & 0xff; + mPathID = (*(s32 *)¶m1) & 0xff; if (mPathID < 0) mPathID = 0; _ZN7PathPtrC1Ev(&p1); _ZN7PathPtr6FromIDEj(&p1, mPathID); unk_38c = _ZNK7PathPtr8NumNodesEv(&p1); - unk_0a0 = -0x3c000; + mTerminalVelocity = -0x3c000; unk_374 = 0; unk_378 = 0; unk_37c = 0; diff --git a/src/_ZN5Stump13InitResourcesEv.cpp b/src/_ZN5Stump13InitResourcesEv.cpp index 6a7324d7d..541e0a5c7 100644 --- a/src/_ZN5Stump13InitResourcesEv.cpp +++ b/src/_ZN5Stump13InitResourcesEv.cpp @@ -22,26 +22,26 @@ extern char data_ov091_021356d0[]; int Stump::InitResources() { - mVariant = unk_008 & 0xff; - unk_0a0 = -0x1e000; + mVariant = (*(s32 *)¶m1) & 0xff; + mTerminalVelocity = -0x1e000; if (mVariant == 0xff) mVariant = 0; if (mVariant == 1) { _ZN18MovingCylinderClsn4InitEP5Actor5Fix12IiES3_jj(((char *)this) + 0x110, ((char *)this), 0x3c000, 0x14000, 0x200002, 0); func_ov091_02134044(((char *)this), data_ov091_021356c0); _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_(((char *)this) + 0x144, ((char *)this), 0x14000, 0, 0, 0); - unk_0b0 = 0; + (*(s32 *)&mFlags) = 0; return 1; } _ZN18MovingCylinderClsn4InitEP5Actor5Fix12IiES3_jj(((char *)this) + 0x110, ((char *)this), 0x64000, 0x64000, 0x200002, 0x4a010); - unk_0b0 = 0x10000000; + (*(s32 *)&mFlags) = 0x10000000; _ZN5Model8LoadFileER13SharedFilePtr(data_ov002_0210da40); _ZN5Model8LoadFileER13SharedFilePtr(data_ov002_0210d9a0); _ZN5Model8LoadFileER13SharedFilePtr(data_ov002_0210d9c0); _ZN9ModelBase7SetFileEP8BMD_Fileii(((char *)this) + 0x300, _ZN5Model8LoadFileER13SharedFilePtr(data_ov091_02135674), 1, -1); _ZN9Animation8LoadFileER13SharedFilePtr(data_ov091_0213567c); _ZN9Animation8LoadFileER13SharedFilePtr(data_ov091_02135684); - unk_35c = 0x1000; + (*(s32 *)((char *)&mModelAnim + 0x5c)) = 0x1000; func_ov091_02134044(((char *)this), data_ov091_021356d0); return 1; } diff --git a/src/_ZN5Stump16CleanupResourcesEv.cpp b/src/_ZN5Stump16CleanupResourcesEv.cpp index c514cca85..f2d5c12c7 100644 --- a/src/_ZN5Stump16CleanupResourcesEv.cpp +++ b/src/_ZN5Stump16CleanupResourcesEv.cpp @@ -2,7 +2,6 @@ // @symbol _ZN5Stump16CleanupResourcesEv /* recovered: named members + shared header, real C++ method */ #include "Stump.h" -struct SharedFilePtr { unsigned int data[4]; }; extern "C" { extern void _ZN13SharedFilePtr7ReleaseEv(struct SharedFilePtr *self); } diff --git a/src/_ZN5Stump6RenderEv.cpp b/src/_ZN5Stump6RenderEv.cpp index c9b9fb724..03a761d0a 100644 --- a/src/_ZN5Stump6RenderEv.cpp +++ b/src/_ZN5Stump6RenderEv.cpp @@ -9,8 +9,8 @@ struct V { virtual void m0(); virtual void m1(); virtual void m2(); virtual void int Stump::Render() { if (mVariant == 1) return 1; - int b = (unk_0b0 & 0x40000) != 0; + int b = ((*(s32 *)&mFlags) & 0x40000) != 0; if (b) return 1; - ((V*)((char *)&mModelAnim))->m5(0); + ((V*)((char *)&(*(u8 *)&mModelAnim)))->m5(0); return 1; } diff --git a/src/_ZN5Stump8BehaviorEv.cpp b/src/_ZN5Stump8BehaviorEv.cpp index 58ee6f040..21b63d5d8 100644 --- a/src/_ZN5Stump8BehaviorEv.cpp +++ b/src/_ZN5Stump8BehaviorEv.cpp @@ -20,7 +20,6 @@ extern void _ZN5Enemy12UpdateWMClsnER12WithMeshClsnj(Enemy *thiz, WithMeshClsn * extern void _ZN9Animation7AdvanceEv(void *thiz); } -struct Enemy { char pad[0x800]; }; int Stump::Behavior() { diff --git a/src/_ZN5Unagi13InitResourcesEv.cpp b/src/_ZN5Unagi13InitResourcesEv.cpp index e438ed844..4f8045637 100644 --- a/src/_ZN5Unagi13InitResourcesEv.cpp +++ b/src/_ZN5Unagi13InitResourcesEv.cpp @@ -46,9 +46,9 @@ int Unagi::InitResources() _ZN9Animation8LoadFileER13SharedFilePtr(data_ov016_02114d30); _ZN9Animation8LoadFileER13SharedFilePtr(data_ov016_02114d28); - mPathID = mParam & 0xff; - mVariant = (mParam >> 8) & 0xf; - unk_414 = (mParam >> 0xc) & 0xf; + mPathID = param1 & 0xff; + mVariant = (param1 >> 8) & 0xf; + unk_414 = (param1 >> 0xc) & 0xf; if (mVariant == 0xff) mVariant = 0; if (mPathID < 0) @@ -61,7 +61,7 @@ int Unagi::InitResources() unk_3f0 = mPosX; unk_3f4 = mPosY; unk_3f8 = mPosZ; - unk_0a0 = -0x1e000; + mTerminalVelocity = -0x1e000; v1 = data_ov016_02114d4c; _ZN25MovingCylinderClsnWithPos4InitEP5ActorRK7Vector35Fix12IiES6_jj( ((char*)this) + 0x110, ((char*)this), &v1, 0x32000, 0x50000, 0x200004, 0); @@ -73,7 +73,7 @@ int Unagi::InitResources() _ZN7PathPtr6FromIDEj(&path2, mPathID); unk_410 = 1; mStarUniqueID = 0; - unk_3ac = 0x1000; + (*(s32 *)((char *)&mBlendModelAnim + 0x5c)) = 0x1000; if (data_0209f220 == 1) goto check_param2; diff --git a/src/_ZN5UnagiD0Ev.cpp b/src/_ZN5UnagiD0Ev.cpp index bd4af6bea..62d72d844 100644 --- a/src/_ZN5UnagiD0Ev.cpp +++ b/src/_ZN5UnagiD0Ev.cpp @@ -1,26 +1,18 @@ //cpp // @symbol _ZN5UnagiD0Ev -/* recovered: named members + shared header, declarations from a shared header */ -#include "decl_BlendModelAnim.h" -#include "decl_WithMeshClsn.h" -#include "decl_common.h" -/* recovered: named members + shared header */ +/* recovered: real C++ deleting destructor -- the compiler emits the whole body + * + * Destroy through Unagi and Enemy, then hand the object back through Actor's + * inline operator delete, which is why nothing here mentions a heap. The array + * cleanup at 0x448 is Vector3[7]; see the note in the D1 file. + * + * The hand-written version declared its own `extern void *data_020a0eac[]`, + * which collides with the `void *` Actor.h supplies for that same heap once the + * real header is in scope. Declaring the destructor is enough; the compiler + * writes the rest. + */ #include "Unagi.h" -extern "C" { -extern int __destroy_arr(void*,int,int,void*); -extern void _ZN25MovingCylinderClsnWithPosD1Ev(void*); -extern int _ZN5EnemyD2Ev(int*); -extern void func_020072c0(void); -extern void* data_020a0eac[]; -void* _ZN5UnagiD0Ev(struct Unagi *self) { - *(int**)((char*)self) = _ZTV5Unagi; - __destroy_arr(((char*)self)+0x448, 7, 0xc, (void*)func_020072c0); - _ZN14BlendModelAnimD1Ev((char*)&self->mBlendModelAnim); - _ZN12WithMeshClsnD1Ev((char*)&self->mWithMeshClsn); - _ZN25MovingCylinderClsnWithPosD1Ev((char*)&self->mMovingCylinderClsnWithPos2); - _ZN25MovingCylinderClsnWithPosD1Ev((char*)&self->mMovingCylinderClsnWithPos1); - _ZN5EnemyD2Ev((int*)((char*)self)); - _ZN6Memory10DeallocateEPvP4Heap(((char*)self), data_020a0eac[0]); - return ((char*)self); -} + +Unagi::~Unagi() +{ } diff --git a/src/_ZN5UnagiD1Ev.c b/src/_ZN5UnagiD1Ev.c deleted file mode 100644 index f87c6be07..000000000 --- a/src/_ZN5UnagiD1Ev.c +++ /dev/null @@ -1,22 +0,0 @@ -// @symbol _ZN5UnagiD1Ev -/* recovered: named members + shared header, declarations from a shared header */ -#include "decl_BlendModelAnim.h" -#include "decl_WithMeshClsn.h" -#include "decl_common.h" -/* recovered: named members + shared header */ -#include "Unagi.h" -extern int __destroy_arr(void*, int, int, void*); -extern void _ZN25MovingCylinderClsnWithPosD1Ev(void*); -extern int _ZN5EnemyD2Ev(int*); -extern void func_020072c0(void); - -int _ZN5UnagiD1Ev(struct Unagi *self) { - *(void**)((void*)self) = _ZTV5Unagi; - __destroy_arr((char*)((void*)self) + 0x448, 7, 0xc, (void*)func_020072c0); - _ZN14BlendModelAnimD1Ev((char*)&self->mBlendModelAnim); - _ZN12WithMeshClsnD1Ev((char*)&self->mWithMeshClsn); - _ZN25MovingCylinderClsnWithPosD1Ev((char*)&self->mMovingCylinderClsnWithPos2); - _ZN25MovingCylinderClsnWithPosD1Ev((char*)&self->mMovingCylinderClsnWithPos1); - _ZN5EnemyD2Ev((int*)((void*)self)); - return (int)((void*)self); -} diff --git a/src/_ZN5UnagiD1Ev.cpp b/src/_ZN5UnagiD1Ev.cpp new file mode 100644 index 000000000..f4dcb1d53 --- /dev/null +++ b/src/_ZN5UnagiD1Ev.cpp @@ -0,0 +1,15 @@ +//cpp +// @symbol _ZN5UnagiD1Ev +/* recovered: real C++ destructor -- the compiler emits the whole body + * + * One array cleanup, four member destructors and the chain into Enemy, all of + * it reverse declaration order out of Unagi.h. + * + * The array at 0x448 is Vector3[7] -- the ROM destroys it with + * __destroy_arr(ptr, 7, 0xc, _ZN7Vector3D1Ev), and 0xc is sizeof(Vector3). + */ +#include "Unagi.h" + +Unagi::~Unagi() +{ +} diff --git a/src/_ZN6EyerokD0Ev.c b/src/_ZN6EyerokD0Ev.c index 12519dbe1..85cb1a83c 100644 --- a/src/_ZN6EyerokD0Ev.c +++ b/src/_ZN6EyerokD0Ev.c @@ -11,13 +11,13 @@ extern void _ZN25MovingCylinderClsnWithPosD1Ev(void*); extern void _ZN5ActorD2Ev(void*); extern void* _ZN6Memory10DeallocateEPvP4Heap(void*, void*); extern int _ZTV6Eyerok[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int _ZTV8Platform[]; extern void* data_020a0eac; void* _ZN6EyerokD0Ev(struct Eyerok *self) { *(int**)((char*)self) = _ZTV6Eyerok; _ZN18MovingMeshColliderD1Ev((char*)&self->unk_674); - __destroy_arr(((char*)self)+0x4dc, 0x14, 0xc, func_020072c0); + __destroy_arr(((char*)self)+0x4dc, 0x14, 0xc, _ZN7Vector3D1Ev); _ZN15TextureSequenceD1Ev((char*)&self->mTextureSequence); _ZN11ShadowModelD1Ev((char*)&self->mShadowModel); _ZN5ModelD1Ev((char*)&self->mModel2); diff --git a/src/_ZN6EyerokD1Ev.c b/src/_ZN6EyerokD1Ev.c index bc2b079b4..fcee41267 100644 --- a/src/_ZN6EyerokD1Ev.c +++ b/src/_ZN6EyerokD1Ev.c @@ -12,11 +12,11 @@ extern void _ZN15TextureSequenceD1Ev(void* p); extern void _ZN25MovingCylinderClsnWithPosD1Ev(void* p); extern int __destroy_arr(void* p, int a, int b, void* fn); extern int _ZTV8Platform[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; void* _ZN6EyerokD1Ev(struct Eyerok *self) { *(void**)((char*)self) = _ZTV6Eyerok; _ZN18MovingMeshColliderD1Ev((char*)&self->unk_674); - __destroy_arr(((char*)self)+0x4dc, 0x14, 0xc, func_020072c0); + __destroy_arr(((char*)self)+0x4dc, 0x14, 0xc, _ZN7Vector3D1Ev); _ZN15TextureSequenceD1Ev((char*)&self->mTextureSequence); _ZN11ShadowModelD1Ev((char*)&self->mShadowModel); _ZN5ModelD1Ev((char*)&self->mModel2); diff --git a/src/_ZN6Player12ShowMessage2ER9ActorBasejPK7Vector3hh.cpp b/src/_ZN6Player12ShowMessage2ER9ActorBasejPK7Vector3hh.cpp index 16edf1e81..f8b15f03a 100644 --- a/src/_ZN6Player12ShowMessage2ER9ActorBasejPK7Vector3hh.cpp +++ b/src/_ZN6Player12ShowMessage2ER9ActorBasejPK7Vector3hh.cpp @@ -24,7 +24,7 @@ extern Player::State data_ov002_0211022c; extern int data_ov002_0210e15c; extern int data_ov002_0210f224[3]; extern int data_ov002_0210f1ac; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void *data_0209f318; void _ZN6Player11ChangeStateERNS_5StateE(void *thiz, Player::State *st); @@ -78,7 +78,7 @@ int Player::ShowMessage2(ActorBase & actor_, unsigned int msg, const Vector3 * p data_ov002_0210f224[0] = 0; data_ov002_0210f224[1] = 0x64000; data_ov002_0210f224[2] = 0x64000; - func_020731dc(data_ov002_0210f224, (void *)func_020072c0, &data_ov002_0210f1ac); + func_020731dc(data_ov002_0210f224, (void *)_ZN7Vector3D1Ev, &data_ov002_0210f1ac); data_ov002_0210e15c |= 1; } diff --git a/src/_ZN6Player13InitResourcesEv.cpp b/src/_ZN6Player13InitResourcesEv.cpp index 677543864..f1e1c7c27 100644 --- a/src/_ZN6Player13InitResourcesEv.cpp +++ b/src/_ZN6Player13InitResourcesEv.cpp @@ -37,7 +37,7 @@ extern "C" { void _ZN4BgCh19StartDetectingWaterEv(void* p); int StartWithFarCamera(void); void _ZN13RaycastGroundD1Ev(void* p); - void func_020072c0(void); + void _ZN7Vector3D1Ev(void); void func_0203d384(void); extern u8 data_0209f2d8; @@ -117,7 +117,7 @@ s32 Player::InitResources() Ld0: func_ov002_020e5948(c); if (changed != 0) func_ov002_020beabc(c); - *(void**)(&unk_578) = func_02073470(0x32, 0xc, 8, (void*)func_0203d384, (void*)func_020072c0); + *(void**)(&unk_578) = func_02073470(0x32, 0xc, 8, (void*)func_0203d384, (void*)_ZN7Vector3D1Ev); *(void**)(&unk_57c) = _ZN6Memory13operator_new2Ej(0x32); *(void**)(&mHeldObjQueue) = _ZN6Memory13operator_new2Ej(0x14); q = *(u8**)(&mHeldObjQueue); diff --git a/src/_ZN6Player16CleanupResourcesEv.cpp b/src/_ZN6Player16CleanupResourcesEv.cpp index 7c67afb8e..cceff7a21 100644 --- a/src/_ZN6Player16CleanupResourcesEv.cpp +++ b/src/_ZN6Player16CleanupResourcesEv.cpp @@ -19,7 +19,7 @@ void func_ov002_020bdef0(char *c); void func_ov002_020bdd9c(char *c); void func_ov002_020e032c(char *c); void func_0203cbc0(int p); -void func_020072c0(void); +void _ZN7Vector3D1Ev(void); void func_02073244(int p, int a, int b, void (*f)(void)); void func_ov002_020bebd4(char *c); void UnloadSilverStarAndNumber(void); @@ -94,7 +94,7 @@ int Player::CleanupResources() { int q = unk_578; if (q != 0) - func_02073244(q, 0xc, 8, func_020072c0); + func_02073244(q, 0xc, 8, _ZN7Vector3D1Ev); q = unk_57c; if (q != 0) func_0203cbc0(q); diff --git a/src/_ZN6Player16TryEnterStarDoorER7Vector3s.cpp b/src/_ZN6Player16TryEnterStarDoorER7Vector3s.cpp index 1d35b4d30..ea2d0605c 100644 --- a/src/_ZN6Player16TryEnterStarDoorER7Vector3s.cpp +++ b/src/_ZN6Player16TryEnterStarDoorER7Vector3s.cpp @@ -15,7 +15,7 @@ extern Player::State data_ov002_0211043c; /* crouch */ extern int data_ov002_0210e164; extern int data_ov002_0210f344[3]; extern int data_ov002_0210f308; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern int _ZN6Player17SetNoControlStateEhih(void *c, unsigned char a, int b, unsigned char d); extern void func_020731dc(int a, int b, void **node); @@ -39,7 +39,7 @@ int Player::TryEnterStarDoor(Vector3 & pos_, short kind) data_ov002_0210f344[0] = 0; data_ov002_0210f344[1] = 0; data_ov002_0210f344[2] = 0x64000; - func_020731dc((int)data_ov002_0210f344, (int)func_020072c0, (void **)&data_ov002_0210f308); + func_020731dc((int)data_ov002_0210f344, (int)_ZN7Vector3D1Ev, (void **)&data_ov002_0210f308); data_ov002_0210e164 |= 1; } Vec3_RotateYAndTranslate(&unk_744, &unk_750, unk_69e, data_ov002_0210f344); diff --git a/src/_ZN6Rabbit8BehaviorEv.cpp b/src/_ZN6Rabbit8BehaviorEv.cpp index dd5f8d1db..2a51bf4d5 100644 --- a/src/_ZN6Rabbit8BehaviorEv.cpp +++ b/src/_ZN6Rabbit8BehaviorEv.cpp @@ -45,6 +45,14 @@ * it wants its own slice. */ #include "Rabbit.h" + +/* A LOCAL COORDINATE TRIPLE, NOT A Vector3 OBJECT. Vector3 declares a + destructor (see include/types.h -- the ROM's __destroy_arr calls prove the + type has one), so a Vector3 local would be destroyed at scope exit and this + function would come out 8 bytes long. The ROM emits no cleanup for either of + these, which is itself the evidence that they were never Vector3s: they are + scratch x/y/z the code fills and reads back. */ +typedef volatile struct { Fix12i x, y, z; } Vec3Scratch; typedef s32 Fix12; @@ -108,7 +116,7 @@ int Rabbit::Behavior() data_0209f33c = c; if (unk_429 != 0) { - volatile Vector3 pv; + Vec3Scratch pv; pv.x = mPosX; pv.y = mPosY; pv.z = mPosZ; @@ -125,7 +133,7 @@ int Rabbit::Behavior() void* temp_r4 = *(void**)&unk_45c; if (temp_r4 != 0) { if (temp_r1 == 0) { - volatile Vector3 pos; + Vec3Scratch pos; int var_r6; int var_r2; int t; diff --git a/src/_ZN7Minimap8BehaviorEv.cpp b/src/_ZN7Minimap8BehaviorEv.cpp index 17d65a50a..ed2c306a7 100644 --- a/src/_ZN7Minimap8BehaviorEv.cpp +++ b/src/_ZN7Minimap8BehaviorEv.cpp @@ -23,7 +23,6 @@ * The header's u16 says the same thing without the casts. */ #include "Minimap.h" -typedef int Fix12; struct Obj { char pad0[0x5c]; @@ -82,10 +81,10 @@ extern s32 _ZN6Player12Unk_020ca8f8Ev(Obj *p); extern void SetSubBg2Offset(s32 a, s32 b); extern void _ZN3G2x13SetBlendAlphaEPVttttt(volatile u16 *p, u16 a, u16 b, u16 c, u16 d); extern s32 SublevelToLevel(s32 i); -extern Fix12 _ZN4cstd4fdivEii(s32 a, s32 b); +extern int _ZN4cstd4fdivEii(s32 a, s32 b); extern void _ZN7Minimap21FixTHIPaintingRoomPosER7Vector3(Vector3 *v); -extern void _ZN7Minimap15GetPosOnMinimapER7Vector3S1_5Fix12IiEsS1_(Vector3 *a, Vector3 *b, Fix12 c, s16 d, Vector3 *e); -extern void _ZN7Minimap20GetPosFromMinimapPosER7Vector3S1_5Fix12IiEsS1_(Vector3 *a, Vector3 *b, Fix12 c, s16 d, Vector3 *e); +extern void _ZN7Minimap15GetPosOnMinimapER7Vector3S1_5Fix12IiEsS1_(Vector3 *a, Vector3 *b, int c, s16 d, Vector3 *e); +extern void _ZN7Minimap20GetPosFromMinimapPosER7Vector3S1_5Fix12IiEsS1_(Vector3 *a, Vector3 *b, int c, s16 d, Vector3 *e); extern void Vec3_Sub(Vector3 *out, Vector3 *a, Vector3 *b); extern void AddVec3(Vector3 *a, Vector3 *b, Vector3 *c); extern s32 GetMinimapID(Obj *obj, s32 arg); diff --git a/src/_ZN7Vector3D1Ev.cpp b/src/_ZN7Vector3D1Ev.cpp new file mode 100644 index 000000000..a0a95280a --- /dev/null +++ b/src/_ZN7Vector3D1Ev.cpp @@ -0,0 +1,39 @@ +//cpp +// @symbol _ZN7Vector3D1Ev +/* recovered: Vector3's destructor, and it does nothing + * + * This file was _ZN7Vector3D1Ev.c -- four bytes, `bx lr`, an empty function + * nothing claimed. It is Vector3::~Vector3, and the ROM proves it: six classes + * destroy arrays of a 0xc type through + * `__destroy_arr(ptr, N, 0xc, _ZN7Vector3D1Ev)`, a POD array needs no cleanup at + * all, and ChiefChilly::InitResources fills those elements as x/y/z from the + * actor's position. types.h defines Vector3 as exactly `Fix12i x, y, z`. + * + * Compiling `Vector3 a[8]` inside a class with a destructor emits + * __cxa_vec_cleanup -- which IS __destroy_arr (PR #1353) -- against this + * symbol, which is the ROM's call verbatim. + * + * The body being empty is not an omission: a declared destructor that does + * nothing is exactly what makes the compiler emit the array cleanup while + * leaving the element work to nobody. + */ +#include "types.h" + +/* ~Vector3 is defined inline in types.h -- it has to be, because every class + holding a Vector3 array needs the body visible to emit the array cleanup. So + this file cannot define it again, and a TU that merely includes the header + emits nothing. + A plain explicit destructor call is not enough either: the body is empty, so + the compiler inlines it away and still emits no out-of-line copy. What DOES + force one is the thing this symbol exists for -- an ARRAY cleanup, which has + to pass the destructor's address to __cxa_vec_cleanup and therefore cannot + inline it. Never instantiated; objisolate keeps the declared function and + drops the rest. */ +struct Vector3_ForceDestructor { + Vector3 v[2]; + ~Vector3_ForceDestructor(); +}; + +Vector3_ForceDestructor::~Vector3_ForceDestructor() +{ +} diff --git a/src/_ZN7WigglerD0Ev.c b/src/_ZN7WigglerD0Ev.c deleted file mode 100644 index 9e8455557..000000000 --- a/src/_ZN7WigglerD0Ev.c +++ /dev/null @@ -1,30 +0,0 @@ -// @symbol _ZN7WigglerD0Ev -/* recovered: named members + shared header */ -#include "Wiggler.h" -extern void _ZN12WithMeshClsnD1Ev(void *); -extern void __destroy_arr(void *p, int count, int size, void *dtor); -extern int _ZN5EnemyD2Ev(int *x); -extern void _ZN6Memory10DeallocateEPvP4Heap(void *p, void *h); -extern char _ZTV7Wiggler[]; -extern void _ZN25MovingCylinderClsnWithPosD1Ev(void); -extern void func_02011508(void); -extern void func_020072c0(void); -extern void _ZN15TextureSequenceD1Ev(void); -extern void _ZN15MaterialChangerD1Ev(void); -extern void _ZN9ModelAnimD1Ev(void); -extern void *data_020a0eac; -int _ZN7WigglerD0Ev(struct Wiggler *self) { - *(void**)((char *)self) = _ZTV7Wiggler; - _ZN12WithMeshClsnD1Ev((char *)&self->mWithMeshClsn); - __destroy_arr(((char *)self)+0x5b8, 5, 0x40, (void*)_ZN25MovingCylinderClsnWithPosD1Ev); - __destroy_arr(((char *)self)+0x478, 5, 0x40, (void*)_ZN25MovingCylinderClsnWithPosD1Ev); - __destroy_arr(((char *)self)+0x444, 5, 6, (void*)func_02011508); - __destroy_arr(((char *)self)+0x408, 5, 0xc, (void*)func_020072c0); - __destroy_arr(((char *)self)+0x3cc, 5, 0xc, (void*)func_020072c0); - __destroy_arr(((char *)self)+0x368, 5, 0x14, (void*)_ZN15TextureSequenceD1Ev); - __destroy_arr(((char *)self)+0x304, 5, 0x14, (void*)_ZN15MaterialChangerD1Ev); - __destroy_arr(((char *)self)+0x110, 5, 0x64, (void*)_ZN9ModelAnimD1Ev); - _ZN5EnemyD2Ev((int*)((char *)self)); - _ZN6Memory10DeallocateEPvP4Heap(((char *)self), data_020a0eac); - return (int)((char *)self); -} diff --git a/src/_ZN7WigglerD0Ev.cpp b/src/_ZN7WigglerD0Ev.cpp new file mode 100644 index 000000000..dd8630245 --- /dev/null +++ b/src/_ZN7WigglerD0Ev.cpp @@ -0,0 +1,18 @@ +//cpp +// @symbol _ZN7WigglerD0Ev +/* recovered: real C++ deleting destructor -- the compiler emits the whole body + * + * D0 is the DELETING destructor: destroy through this class and its bases -- + * which is why more than one vptr store appears -- then return the object to + * its heap. Nobody writes that; declaring `~Wiggler()` is enough, because mwcc + * emits D2, D0 and D1 together and objisolate keeps the one this file is bound + * to. + * + * The deallocation is an inline operator delete, which is why nothing below + * mentions a heap. + */ +#include "Wiggler.h" + +Wiggler::~Wiggler() +{ +} diff --git a/src/_ZN7WigglerD1Ev.c b/src/_ZN7WigglerD1Ev.c deleted file mode 100644 index 8000439ad..000000000 --- a/src/_ZN7WigglerD1Ev.c +++ /dev/null @@ -1,27 +0,0 @@ -// @symbol _ZN7WigglerD1Ev -/* recovered: named members + shared header */ -#include "Wiggler.h" -extern int _ZN12WithMeshClsnD1Ev(void *p); -extern int __destroy_arr(void *p, int a, int b, void *f); -extern int _ZN5EnemyD2Ev(void *p); -extern int _ZN25MovingCylinderClsnWithPosD1Ev(void *p); -extern int func_02011508(void *p); -extern int func_020072c0(void *p); -extern int _ZN15TextureSequenceD1Ev(void *p); -extern int _ZN15MaterialChangerD1Ev(void *p); -extern int _ZN9ModelAnimD1Ev(void *p); -extern int _ZTV7Wiggler[]; -int _ZN7WigglerD1Ev(struct Wiggler *self) { - *(int**)(((char *)self)) = _ZTV7Wiggler; - _ZN12WithMeshClsnD1Ev((char *)&self->mWithMeshClsn); - __destroy_arr(((char *)self)+0x5b8, 5, 0x40, _ZN25MovingCylinderClsnWithPosD1Ev); - __destroy_arr(((char *)self)+0x478, 5, 0x40, _ZN25MovingCylinderClsnWithPosD1Ev); - __destroy_arr(((char *)self)+0x444, 5, 6, func_02011508); - __destroy_arr(((char *)self)+0x408, 5, 0xc, func_020072c0); - __destroy_arr(((char *)self)+0x3cc, 5, 0xc, func_020072c0); - __destroy_arr(((char *)self)+0x368, 5, 0x14, _ZN15TextureSequenceD1Ev); - __destroy_arr(((char *)self)+0x304, 5, 0x14, _ZN15MaterialChangerD1Ev); - __destroy_arr(((char *)self)+0x110, 5, 0x64, _ZN9ModelAnimD1Ev); - _ZN5EnemyD2Ev(((char *)self)); - return (int)((char *)self); -} diff --git a/src/_ZN7WigglerD1Ev.cpp b/src/_ZN7WigglerD1Ev.cpp new file mode 100644 index 000000000..ee1befebd --- /dev/null +++ b/src/_ZN7WigglerD1Ev.cpp @@ -0,0 +1,16 @@ +//cpp +// @symbol _ZN7WigglerD1Ev +/* recovered: real C++ destructor -- the compiler emits the whole body + * + * Eight array cleanups and the chain into Enemy, reverse declaration order out + * of Wiggler.h. Five body segments, so five of everything: a ModelAnim, a + * MaterialChanger and a TextureSequence each, two Vector3 arrays and a + * Vector3s array of per-segment values, and two sets of collision cylinders. + * + * The Vector3s array at 0x444 is what named func_02011508. + */ +#include "Wiggler.h" + +Wiggler::~Wiggler() +{ +} diff --git a/src/_ZN8Goomboss6RenderEv.cpp b/src/_ZN8Goomboss6RenderEv.cpp index 5f88d2bf6..1b5fbdcfd 100644 --- a/src/_ZN8Goomboss6RenderEv.cpp +++ b/src/_ZN8Goomboss6RenderEv.cpp @@ -16,7 +16,7 @@ struct Sub { int Goomboss::Render() { - if(mParam==0x1111) return func_ov074_021222e0(((char*)this)); + if(param1==0x1111) return func_ov074_021222e0(((char*)this)); if(unk_60a==0) return 1; Sub* s = (Sub*)((char*)&mModelAnim); s->m((char*)&mScaleX); diff --git a/src/_ZN8Goomboss8BehaviorEv.cpp b/src/_ZN8Goomboss8BehaviorEv.cpp index 698887043..9c91c2f91 100644 --- a/src/_ZN8Goomboss8BehaviorEv.cpp +++ b/src/_ZN8Goomboss8BehaviorEv.cpp @@ -25,7 +25,7 @@ int Goomboss::Behavior() int u; int quake; - if (mParam == 0x1111) { + if (param1 == 0x1111) { return func_ov074_021223bc(((char *)this)); } @@ -60,23 +60,23 @@ int Goomboss::Behavior() if (unk_5fe != 0) { if (mSizeIndex >= 2) { Vector3 v; - v.x = unk_3c4; - v.y = unk_3c8; - v.z = unk_3cc; + v.x = unk_3ac[2].x; + v.y = unk_3ac[2].y; + v.z = unk_3ac[2].z; _ZN5Actor17HugeLandingDustAtER7Vector3b(((char *)this), &v, 1); } else { Vector3 v; - v.x = unk_3c4; - v.y = unk_3c8; - v.z = unk_3cc; + v.x = unk_3ac[2].x; + v.y = unk_3ac[2].y; + v.z = unk_3ac[2].z; _ZN5Actor13LandingDustAtER7Vector3b(((char *)this), &v, 1); } func_02012694(0x15e, ((char *)this) + 0x74); { Vector3 v; - v.x = unk_3c4; - v.y = unk_3c8; - v.z = unk_3cc; + v.x = unk_3ac[2].x; + v.y = unk_3ac[2].y; + v.z = unk_3ac[2].z; _ZN5Actor10EarthquakeERK7Vector35Fix12IiE(((char *)this), &v, quake); } } @@ -84,23 +84,23 @@ int Goomboss::Behavior() if (unk_5ff != 0) { if (mSizeIndex >= 2) { Vector3 v; - v.x = unk_3b8; - v.y = unk_3bc; - v.z = unk_3c0; + v.x = unk_3ac[1].x; + v.y = unk_3ac[1].y; + v.z = unk_3ac[1].z; _ZN5Actor17HugeLandingDustAtER7Vector3b(((char *)this), &v, 1); } else { Vector3 v; - v.x = unk_3b8; - v.y = unk_3bc; - v.z = unk_3c0; + v.x = unk_3ac[1].x; + v.y = unk_3ac[1].y; + v.z = unk_3ac[1].z; _ZN5Actor13LandingDustAtER7Vector3b(((char *)this), &v, 1); } func_02012694(0x15e, ((char *)this) + 0x74); { Vector3 v; - v.x = unk_3b8; - v.y = unk_3bc; - v.z = unk_3c0; + v.x = unk_3ac[1].x; + v.y = unk_3ac[1].y; + v.z = unk_3ac[1].z; _ZN5Actor10EarthquakeERK7Vector35Fix12IiE(((char *)this), &v, quake); } } diff --git a/src/_ZN8GoombossD0Ev.c b/src/_ZN8GoombossD0Ev.c index 29196f2d4..aae0af8ee 100644 --- a/src/_ZN8GoombossD0Ev.c +++ b/src/_ZN8GoombossD0Ev.c @@ -3,7 +3,7 @@ #include "Goomboss.h" extern int __destroy_arr(void* c, int a, int b, void* d); extern void* _ZTV8Goomboss[]; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern int _ZN12WithMeshClsnD1Ev(void* c); extern int _ZN18TextureTransformerD1Ev(void* c); extern int _ZN15TextureSequenceD1Ev(void* c); @@ -20,7 +20,7 @@ int _ZN8GoombossD0Ev(struct Goomboss *self) { _ZN18TextureTransformerD1Ev((char*)&self->mTextureTransformer); _ZN15TextureSequenceD1Ev((char*)&self->mTextureSequence); _ZN15MaterialChangerD1Ev((char*)&self->mMaterialChanger); - __destroy_arr((char*)((void*)self)+0x3ac, 3, 0xc, (void*)func_020072c0); + __destroy_arr((char*)((void*)self)+0x3ac, 3, 0xc, (void*)_ZN7Vector3D1Ev); __destroy_arr((char*)((void*)self)+0x274, 3, 0x28, (void*)_ZN11ShadowModelD1Ev); _ZN9ModelAnimD1Ev((char*)&self->mModelAnim); __destroy_arr((char*)((void*)self)+0x110, 4, 0x40, (void*)_ZN25MovingCylinderClsnWithPosD1Ev); diff --git a/src/_ZN8GoombossD1Ev.c b/src/_ZN8GoombossD1Ev.c deleted file mode 100644 index 0e8087641..000000000 --- a/src/_ZN8GoombossD1Ev.c +++ /dev/null @@ -1,27 +0,0 @@ -// @symbol _ZN8GoombossD1Ev -/* recovered: named members + shared header */ -#include "Goomboss.h" -extern int __destroy_arr(void* p, int a, int b, void* d); -extern void _ZN12WithMeshClsnD1Ev(void* p); -extern void _ZN18TextureTransformerD1Ev(void* p); -extern void _ZN15TextureSequenceD1Ev(void* p); -extern void _ZN15MaterialChangerD1Ev(void* p); -extern void _ZN9ModelAnimD1Ev(void* p); -extern int _ZN5EnemyD2Ev(int* x); -extern int func_020072c0; -extern int _ZN11ShadowModelD1Ev; -extern int _ZN25MovingCylinderClsnWithPosD1Ev; -extern int _ZTV8Goomboss[]; -int _ZN8GoombossD1Ev(struct Goomboss *self) { - *(int**)((int*)self) = _ZTV8Goomboss; - _ZN12WithMeshClsnD1Ev((char*)&self->mWithMeshClsn); - _ZN18TextureTransformerD1Ev((char*)&self->mTextureTransformer); - _ZN15TextureSequenceD1Ev((char*)&self->mTextureSequence); - _ZN15MaterialChangerD1Ev((char*)&self->mMaterialChanger); - __destroy_arr((char*)((int*)self)+0x3ac, 3, 0xc, &func_020072c0); - __destroy_arr((char*)((int*)self)+0x274, 3, 0x28, &_ZN11ShadowModelD1Ev); - _ZN9ModelAnimD1Ev((char*)&self->mModelAnim); - __destroy_arr((char*)((int*)self)+0x110, 4, 0x40, &_ZN25MovingCylinderClsnWithPosD1Ev); - _ZN5EnemyD2Ev(((int*)self)); - return (int)((int*)self); -} diff --git a/src/_ZN8GoombossD1Ev.cpp b/src/_ZN8GoombossD1Ev.cpp new file mode 100644 index 000000000..f1443ef65 --- /dev/null +++ b/src/_ZN8GoombossD1Ev.cpp @@ -0,0 +1,14 @@ +//cpp +// @symbol _ZN8GoombossD1Ev +/* recovered: real C++ destructor -- the compiler emits the whole body + * + * Three array cleanups and five member destructors, in reverse declaration + * order out of Goomboss.h. Every element type was already named in the tree: + * MovingCylinderClsnWithPos[4] at 0x110, ShadowModel[3] at 0x274 and + * Vector3[3] at 0x3ac, with 0x40, 0x28 and 0xc as their sizes. + */ +#include "Goomboss.h" + +Goomboss::~Goomboss() +{ +} diff --git a/src/_ZN8IceBlock13InitResourcesEv.cpp b/src/_ZN8IceBlock13InitResourcesEv.cpp index b0a8f794d..3f1ad9d89 100644 --- a/src/_ZN8IceBlock13InitResourcesEv.cpp +++ b/src/_ZN8IceBlock13InitResourcesEv.cpp @@ -16,12 +16,12 @@ extern "C" void _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEs int IceBlock::InitResources() { void* m = _ZN5Model8LoadFileER13SharedFilePtr(data_ov081_02128fd8); - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this)+0xd4, m, 1, 0x17); + _ZN9ModelBase7SetFileEP8BMD_Fileii((char *)&mModel, m, 1, 0x17); _ZN18MovingCylinderClsn4InitEP5Actor5Fix12IiES3_jj(((char*)this)+0x320, ((char*)this), 0xc8000, 0x12c000, 0x800002, 0x44000); _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); void* k = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov081_02128fd0); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(((char*)this)+0x124, k, ((char*)this)+0x2ec, 0x1000, mAngleY, data_ov002_0210d8d4); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block((char *)&mMeshCollider, k, (char *)&mClsnMat, 0x1000, mAngleY, data_ov002_0210d8d4); mScale = 0x1000; return 1; } diff --git a/src/_ZN8IceBlock16CleanupResourcesEv.cpp b/src/_ZN8IceBlock16CleanupResourcesEv.cpp index 4af06f0c9..efd2e5063 100644 --- a/src/_ZN8IceBlock16CleanupResourcesEv.cpp +++ b/src/_ZN8IceBlock16CleanupResourcesEv.cpp @@ -10,8 +10,8 @@ extern int data_ov081_02128fd8[]; int IceBlock::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(data_ov081_02128fd8))->Release(); ((SharedFilePtr *)(data_ov081_02128fd0))->Release(); diff --git a/src/_ZN8IceBlock8BehaviorEv.cpp b/src/_ZN8IceBlock8BehaviorEv.cpp index fa3220786..f49c26463 100644 --- a/src/_ZN8IceBlock8BehaviorEv.cpp +++ b/src/_ZN8IceBlock8BehaviorEv.cpp @@ -78,18 +78,18 @@ int IceBlock::Behavior() return 1; } - if (unk_344 != 0) { - if ((unk_340 & 0x40000) != 0) { + if ((*(s32 *)((char *)&mMovingCylinderClsn + 0x24)) != 0) { + if (((*(s32 *)((char *)&mMovingCylinderClsn + 0x20)) & 0x40000) != 0) { unk_354 = 0x1e; func_02012694(0x7a, ((char*)this) + 0x74); func_ov081_02127be0(((char*)this)); } - if ((unk_340 & 0x4000) != 0) { + if (((*(s32 *)((char *)&mMovingCylinderClsn + 0x20)) & 0x4000) != 0) { ((VObj*)((char*)this))->OnHit(); } } - _ZN12CylinderClsn5ClearEv((char*)&mMovingCylinderClsn); - _ZN12CylinderClsn6UpdateEv((char*)&mMovingCylinderClsn); + _ZN12CylinderClsn5ClearEv((char*)&(*(u8 *)&mMovingCylinderClsn)); + _ZN12CylinderClsn6UpdateEv((char*)&(*(u8 *)&mMovingCylinderClsn)); return 1; } diff --git a/src/_ZN8IceSheet13InitResourcesEv.cpp b/src/_ZN8IceSheet13InitResourcesEv.cpp index 69c78f572..dd3e93e43 100644 --- a/src/_ZN8IceSheet13InitResourcesEv.cpp +++ b/src/_ZN8IceSheet13InitResourcesEv.cpp @@ -4,23 +4,22 @@ #include "decl_common.h" /* recovered: named members + shared header, real C++ method */ #include "IceSheet.h" -typedef int Fix12; extern "C" { extern void* _ZN5Model8LoadFileER13SharedFilePtr(void*); extern int _ZN9ModelBase7SetFileEP8BMD_Fileii(void*, void*, int, int); extern int _ZN8Platform21UpdateModelPosAndRotYEv(void*); extern int _ZN8Platform19UpdateClsnPosAndRotEv(void*); extern void* _ZN12MeshCollider8LoadFileER13SharedFilePtr(void*); -extern int _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(void*, void*, void*, Fix12, short, void*); +extern int _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(void*, void*, void*, int, short, void*); } int IceSheet::InitResources() { void *mdl = _ZN5Model8LoadFileER13SharedFilePtr(&data_ov018_02113c84); - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char *)this) + 0xd4, mdl, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, mdl, 1, -1); _ZN8Platform21UpdateModelPosAndRotYEv(((char *)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char *)this)); void *kcl = _ZN12MeshCollider8LoadFileER13SharedFilePtr(&data_ov018_02113c7c); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(((char *)this) + 0x124, kcl, ((char *)this) + 0x2ec, 0x199, unk_08e, (void *)&data_ov002_0210d754); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(&mMeshCollider, kcl, &mClsnMat, 0x199, mAngleY, (void *)&data_ov002_0210d754); return 1; } diff --git a/src/_ZN8IceSheet16CleanupResourcesEv.cpp b/src/_ZN8IceSheet16CleanupResourcesEv.cpp index 3f72adc47..bee43a19a 100644 --- a/src/_ZN8IceSheet16CleanupResourcesEv.cpp +++ b/src/_ZN8IceSheet16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int IceSheet_ModelFile[]; int IceSheet::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMovingMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMovingMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(IceSheet_ModelFile))->Release(); ((SharedFilePtr *)(IceSheet_ClsnFile))->Release(); diff --git a/src/_ZN8IceSheet8BehaviorEv.cpp b/src/_ZN8IceSheet8BehaviorEv.cpp index 2a2baf372..244be3693 100644 --- a/src/_ZN8IceSheet8BehaviorEv.cpp +++ b/src/_ZN8IceSheet8BehaviorEv.cpp @@ -8,7 +8,7 @@ extern "C" { int IceSheet::Behavior() { - if (!((MeshColliderBase *)((char*)&mMovingMeshCollider))->IsEnabled()) - ((MeshColliderBase *)(((char*)this)+0x124))->Enable((Actor *)(((char*)this))); + if (!((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)(&mMeshCollider))->Enable((Actor *)(((char*)this))); return 1; } diff --git a/src/_ZN8MetalNet13InitResourcesEv.cpp b/src/_ZN8MetalNet13InitResourcesEv.cpp index 5e0737ca3..295af9189 100644 --- a/src/_ZN8MetalNet13InitResourcesEv.cpp +++ b/src/_ZN8MetalNet13InitResourcesEv.cpp @@ -29,10 +29,10 @@ int MetalNet::InitResources() { struct KCL_File *kcl = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov009_02113e88); _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - ((unsigned char *)this) + 0x124, kcl, *(struct Matrix4x3 *)((unsigned char *)&unk_2ec), 0x1000, - unk_08e, data_ov009_02112bf8); + ((unsigned char *)this) + 0x124, kcl, *(struct Matrix4x3 *)((unsigned char *)&(*(u8 *)&mClsnMat)), 0x1000, + mAngleY, data_ov009_02112bf8); } - if ((unk_008 & 0xff) == 0xff) { + if (((*(s32 *)¶m1) & 0xff) == 0xff) { int b = (int)(data_0209f2d8 == 1); if (b != 0) goto ret1; if ((*(int*)((char*)&data_0209caa0 + 8) & 0x80000) == 0) goto ret1; diff --git a/src/_ZN8MetalNet16CleanupResourcesEv.cpp b/src/_ZN8MetalNet16CleanupResourcesEv.cpp index 375e774a1..991bac7a1 100644 --- a/src/_ZN8MetalNet16CleanupResourcesEv.cpp +++ b/src/_ZN8MetalNet16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int data_ov009_02113e90[]; int MetalNet::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMovingMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMovingMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { + ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); } ((SharedFilePtr *)(data_ov009_02113e90))->Release(); ((SharedFilePtr *)(data_ov009_02113e88))->Release(); diff --git a/src/_ZN8MetalNet8BehaviorEv.cpp b/src/_ZN8MetalNet8BehaviorEv.cpp index 6201e624b..3a32aaf96 100644 --- a/src/_ZN8MetalNet8BehaviorEv.cpp +++ b/src/_ZN8MetalNet8BehaviorEv.cpp @@ -19,7 +19,7 @@ int MetalNet::Behavior() _ZN8Platform19UpdateClsnPosAndRotEv(((void*)this)); b = (int)(data_0209f2d8 == 1); if (b != 0) { - if (((MeshColliderBase *)((char*)&mMovingMeshCollider))->IsEnabled() == 0) + if (((MeshColliderBase *)((char*)&mMeshCollider))->IsEnabled() == 0) ((MeshColliderBase *)((char*)((void*)this)+0x124))->Enable((Actor *)(((void*)this))); } else { _ZN8Platform13IsClsnInRangeE5Fix12IiES1_(((void*)this), 0, 0); diff --git a/src/_ZN8PathLift9AfterClsnEv.cpp b/src/_ZN8PathLift9AfterClsnEv.cpp index d460b2cff..af314a3ba 100644 --- a/src/_ZN8PathLift9AfterClsnEv.cpp +++ b/src/_ZN8PathLift9AfterClsnEv.cpp @@ -14,7 +14,7 @@ void PathLift::AfterClsn() if (func_ov002_020efedc(((char *)this)) != 0 && unk_44c == 0 && DecIfAbove0_Byte((char *)&unk_42b) == 0) { - int b = unk_00c == 0x1f; + int b = actorID == 0x1f; if (b) { func_02012694(0x6f, ((char *)this) + 0x74); } diff --git a/src/_ZN8PlatformD0Ev.c b/src/_ZN8PlatformD0Ev.c deleted file mode 100644 index b70d992a6..000000000 --- a/src/_ZN8PlatformD0Ev.c +++ /dev/null @@ -1,19 +0,0 @@ -// @symbol _ZN8PlatformD0Ev -/* recovered: named members + shared header, vtable identified, declarations from a shared header */ -#include "decl_Actor.h" -#include "decl_Model.h" -#include "decl_MovingMeshCollider.h" -#include "decl_common.h" -extern int _ZTV8Platform[]; -/* recovered: named members + shared header, vtable identified */ -/* vtable identified: VT0 = _ZTV8Platform */ -extern void *data_020a0eac; -int *_ZN8PlatformD0Ev(int *t) -{ - t[0] = (int)_ZTV8Platform; - _ZN18MovingMeshColliderD1Ev((char *)t + 0x124); - _ZN5ModelD1Ev((char *)t + 0xd4); - _ZN5ActorD2Ev(t); - _ZN6Memory10DeallocateEPvP4Heap(t, data_020a0eac); - return t; -} diff --git a/src/_ZN8PlatformD0Ev.cpp b/src/_ZN8PlatformD0Ev.cpp new file mode 100644 index 000000000..2d705aaae --- /dev/null +++ b/src/_ZN8PlatformD0Ev.cpp @@ -0,0 +1,22 @@ +//cpp +// @symbol _ZN8PlatformD0Ev +/* recovered: real C++ deleting destructor, defined inline in the header + * + * ~Platform is defined in the class body -- the seventy-odd classes derived + * from it inline its vptr store rather than calling it, which the compiler can + * only do from a visible body. So this file cannot define it, and a TU that + * merely includes the header emits nothing. The explicit destructor call below + * forces the whole group into existence; objisolate keeps the one this file is + * bound to and drops the rest. + * + * D0 is the deleting half: destroy through Platform and Actor, then hand the + * object back through Actor's inline operator delete, which is why nothing + * here mentions a heap. + */ +#include "Platform.h" + +/* Not called. Forces the out-of-line copy of the inline destructor group. */ +void Platform_EmitDeletingDestructor(Platform *p) +{ + p->~Platform(); +} diff --git a/src/_ZN8PlatformD1Ev.cpp b/src/_ZN8PlatformD1Ev.cpp index 8527271ec..71f530c9f 100644 --- a/src/_ZN8PlatformD1Ev.cpp +++ b/src/_ZN8PlatformD1Ev.cpp @@ -3,18 +3,19 @@ /* recovered: real C++ destructor, defined inline in the header * * ~Platform is defined in the class body, not here, and that is load-bearing: - * the 72 classes derived from Platform inline this destructor's vptr store - * rather than calling it, which the compiler can only do from a visible body. - * include/ActorDerived.h records the measurement behind that. + * the seventy-odd classes derived from Platform inline this destructor's vptr + * store rather than calling it, which the compiler can only do from a visible + * body. include/Platform.h records the measurement. * * So this file cannot define it -- that would be a redefinition -- and a TU - * that merely includes the header emits nothing. The explicit destructor call - * below forces the out-of-line copy the vtable points at into existence. It is - * never called, and objisolate drops it. + * that merely includes the header emits nothing at all. The explicit + * destructor call below is what forces the out-of-line copy the vtable points + * at into existence. It is never called; objisolate keeps the function this + * file declares and drops the rest. * - * The body it forces is the layout evidence for the whole class: the ROM - * destroys a MovingMeshCollider at 0x124 and a Model at 0xd4, and both of - * those offsets are where those classes' own asserted sizes put them. + * The body it forces is the class's own layout evidence: the ROM destroys a + * MovingMeshCollider at 0x124 and a Model at 0xd4, and both offsets are where + * those classes' asserted sizes put them. */ #include "Platform.h" diff --git a/src/_ZN8ShipWing13InitResourcesEv.cpp b/src/_ZN8ShipWing13InitResourcesEv.cpp index 25c74f2da..4e703e10e 100644 --- a/src/_ZN8ShipWing13InitResourcesEv.cpp +++ b/src/_ZN8ShipWing13InitResourcesEv.cpp @@ -20,16 +20,16 @@ extern void _ZN16MeshColliderBase21UpdatePosWithVelocityERS_P5ActorR10ClsnResult int ShipWing::InitResources() { int m = _ZN5Model8LoadFileER13SharedFilePtr(data_ov036_0211408c); - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this)+0xd4, m, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, m, 1, -1); _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); int k = _ZN12MeshCollider8LoadFileER13SharedFilePtr(data_ov036_02114084); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(((char*)this)+0x124, k, ((char*)this)+0x2ec, 0x1000, mAngleY, data_ov036_02112b48); - func_020393d4(((char*)this)+0x124, (void*)_ZN16MeshColliderBase21UpdatePosWithVelocityERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); - func_020393c4(((char*)this)+0x124, (void*)func_ov036_02111cc4); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(&mMeshCollider, k, &mClsnMat, 0x1000, mAngleY, data_ov036_02112b48); + func_020393d4(&mMeshCollider, (void*)_ZN16MeshColliderBase21UpdatePosWithVelocityERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + func_020393c4(&mMeshCollider, (void*)func_ov036_02111cc4); _ZN12WithMeshClsn4InitEP5Actor5Fix12IiES3_P10Vector3_16S5_(((char*)this)+0x320, ((char*)this), 0x32000, 0x64000, 0, 0); - unk_0a0 = -0x1e000; - unk_09c = ~0x198; + mTerminalVelocity = -0x1e000; + mVertAccel = ~0x198; unk_4dc = mPosX; unk_4e0 = mPosY; unk_4e4 = mPosZ; diff --git a/src/_ZN8ShipWing16CleanupResourcesEv.cpp b/src/_ZN8ShipWing16CleanupResourcesEv.cpp index 7074c1c9a..4301fbd57 100644 --- a/src/_ZN8ShipWing16CleanupResourcesEv.cpp +++ b/src/_ZN8ShipWing16CleanupResourcesEv.cpp @@ -10,8 +10,8 @@ extern int data_ov036_0211408c[]; int ShipWing::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(data_ov036_0211408c))->Release(); ((SharedFilePtr *)(data_ov036_02114084))->Release(); diff --git a/src/_ZN8ShipWing8BehaviorEv.cpp b/src/_ZN8ShipWing8BehaviorEv.cpp index 1b43c82fb..369ffb1eb 100644 --- a/src/_ZN8ShipWing8BehaviorEv.cpp +++ b/src/_ZN8ShipWing8BehaviorEv.cpp @@ -34,7 +34,7 @@ int ShipWing::Behavior() if (_ZN5Actor13DistToCPlayerEv(((char*)this)) <= 0x9c4000) break; } _ZN5Actor14TriplePoofDustEv(((char*)this)); - if (((MeshColliderBase *)((char*)&mMeshCollider))->IsEnabled() != 0) ((MeshColliderBase *)((char*)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->IsEnabled() != 0) ((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->Disable(); mPosX = unk_4dc; mPosY = unk_4e0; mPosZ = unk_4e4; @@ -44,7 +44,7 @@ int ShipWing::Behavior() int d = _ZN5Actor13DistToCPlayerEv(((char*)this)); if (d <= 0x3e8000) break; if (d < 0x7d0000) { - unk_0a8 = 0; + mVertSpeed = 0; unk_4e9 = 0; unk_4e8 = 0; mState = 0; diff --git a/src/_ZN8Squasher13InitResourcesEv.cpp b/src/_ZN8Squasher13InitResourcesEv.cpp index 3a24b7429..0532c6eda 100644 --- a/src/_ZN8Squasher13InitResourcesEv.cpp +++ b/src/_ZN8Squasher13InitResourcesEv.cpp @@ -20,14 +20,14 @@ extern void _ZN16MeshColliderBase22UpdatePosWithTransformERS_P5ActorR10ClsnResul int Squasher::InitResources() { int bmd = _ZN5Model8LoadFileER13SharedFilePtr(&data_ov023_02112088); - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char*)this)+0xd4, bmd, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, bmd, 1, -1); _ZN11ShadowModel10InitCuboidEv((char*)&mShadowModel); func_ov023_02111308(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); int kcl = _ZN12MeshCollider8LoadFileER13SharedFilePtr(&_ZN32FloatOnWaterPlatformWdwRectangleD1Ev); - _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(((char*)this)+0x124, kcl, (struct Matrix4x3*)((char*)&unk_2ec), 0x1000, mAngleY, &data_ov064_0211ba4c); + _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block(&mMeshCollider, kcl, (struct Matrix4x3*)((char*)&(*(u8 *)&mClsnMat)), 0x1000, (*(u16 *)&mAngleY), &data_ov064_0211ba4c); func_020393d4((int*)((char*)&mMeshCollider), (int)&_ZN16MeshColliderBase22UpdatePosWithTransformERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); - ((MeshColliderBase *)(((char*)this)+0x124))->Enable((Actor *)(((char*)this))); + ((MeshColliderBase *)(&mMeshCollider))->Enable((Actor *)(((char*)this))); unk_31e = 0; unk_320 = 0; unk_322 = 0; diff --git a/src/_ZN8Vector3sD1Ev.cpp b/src/_ZN8Vector3sD1Ev.cpp new file mode 100644 index 000000000..12fd6edc0 --- /dev/null +++ b/src/_ZN8Vector3sD1Ev.cpp @@ -0,0 +1,26 @@ +//cpp +// @symbol _ZN8Vector3sD1Ev +/* recovered: Vector3s's destructor, and it does nothing + * + * This file was _ZN8Vector3sD1Ev.c -- four bytes, `bx lr`, an empty function + * nothing claimed. It is Vector3s::~Vector3s, on the same evidence that named + * Vector3's: Wiggler destroys an array of a 6-byte type with + * __destroy_arr(this + 0x444, 5, 6, ...), a POD array needs no cleanup at all, + * and types.h defines Vector3s as exactly `s16 x, y, z`. + * + * The forcing shape below is the one Vector3's file needs too -- an explicit + * `p->~Vector3s()` on an empty inline destructor is inlined away and emits no + * out-of-line copy, while an ARRAY cleanup has to pass the destructor's address + * to __cxa_vec_cleanup and therefore cannot. Never instantiated; objisolate + * keeps the declared function and drops the rest. + */ +#include "types.h" + +struct Vector3s_ForceDestructor { + Vector3s v[2]; + ~Vector3s_ForceDestructor(); +}; + +Vector3s_ForceDestructor::~Vector3s_ForceDestructor() +{ +} diff --git a/src/_ZN9HugeCover13InitResourcesEv.cpp b/src/_ZN9HugeCover13InitResourcesEv.cpp index 0b15190be..0ce22ab68 100644 --- a/src/_ZN9HugeCover13InitResourcesEv.cpp +++ b/src/_ZN9HugeCover13InitResourcesEv.cpp @@ -6,9 +6,6 @@ typedef int Fix12i; struct SharedFilePtr; struct BMD_File; struct BTA_File; struct KCL_File; struct Matrix4x3; struct CLPS_Block; struct Actor; /* Model and ModelBase are the real classes now, through HugeCover.h. */ -struct TextureTransformer { int d; }; -struct MeshCollider { int d; }; -struct MovingMeshCollider { int d; }; extern "C" BMD_File* _ZN5Model8LoadFileER13SharedFilePtr(SharedFilePtr&); extern "C" void _ZN9ModelBase7SetFileEP8BMD_Fileii(ModelBase*, BMD_File*, int, int); diff --git a/src/_ZN9HugeCover16CleanupResourcesEv.cpp b/src/_ZN9HugeCover16CleanupResourcesEv.cpp index 948c26546..268a0bf4c 100644 --- a/src/_ZN9HugeCover16CleanupResourcesEv.cpp +++ b/src/_ZN9HugeCover16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int data_ov032_02113afc[]; int HugeCover::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMovingMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMovingMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(data_ov032_02113afc))->Release(); ((SharedFilePtr *)(data_ov032_02113af4))->Release(); diff --git a/src/_ZN9HugeCover8BehaviorEv.cpp b/src/_ZN9HugeCover8BehaviorEv.cpp index 3126b9b27..47eb4f744 100644 --- a/src/_ZN9HugeCover8BehaviorEv.cpp +++ b/src/_ZN9HugeCover8BehaviorEv.cpp @@ -10,8 +10,8 @@ extern void _ZN8Platform19UpdateClsnPosAndRotEv(void *); int HugeCover::Behavior() { - unk_32c = 4096; - _ZN9Animation7AdvanceEv((char *)&mTextureTransformer); + (*(s32 *)((char *)&mTextureTransformer + 0xc)) = 4096; + _ZN9Animation7AdvanceEv((char *)&(*(u8 *)&mTextureTransformer)); _ZN8Platform21UpdateModelPosAndRotYEv(((char *)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char *)this)); return 1; diff --git a/src/_ZN9ModelBase7SetFileEP8BMD_Fileii.cpp b/src/_ZN9ModelBase7SetFileEP8BMD_Fileii.cpp index 2977a6d80..920549d7d 100644 --- a/src/_ZN9ModelBase7SetFileEP8BMD_Fileii.cpp +++ b/src/_ZN9ModelBase7SetFileEP8BMD_Fileii.cpp @@ -2,7 +2,7 @@ // @symbol _ZN9ModelBase7SetFileEP8BMD_Fileii #include "ModelBase.h" -void ModelBase::SetFile(BMD_File *file, int a, int b) +int ModelBase::SetFile(BMD_File *file, int a, int b) { - DoSetFile((char *)file, a, b); + return DoSetFile((char *)file, a, b); } diff --git a/src/_ZN9SeesawBob13InitResourcesEv.cpp b/src/_ZN9SeesawBob13InitResourcesEv.cpp index 681d2b702..e993ecf40 100644 --- a/src/_ZN9SeesawBob13InitResourcesEv.cpp +++ b/src/_ZN9SeesawBob13InitResourcesEv.cpp @@ -20,7 +20,7 @@ int SeesawBob::InitResources() { unsigned char idx; int f; - switch (unk_00c) { + switch (actorID) { case 0x1c: ((char *)this)[0x31e] = 0; break; case 0x27: ((char *)this)[0x31e] = 1; break; case 0x85: ((char *)this)[0x31e] = 2; break; @@ -31,16 +31,16 @@ int SeesawBob::InitResources() } idx = (unsigned char)((char *)this)[0x31e]; f = _ZN5Model8LoadFileER13SharedFilePtr(*(int*)(data_ov095_021374a0 + idx*0xc)); - _ZN9ModelBase7SetFileEP8BMD_Fileii(((char *)this)+0xd4, f, 1, -1); + _ZN9ModelBase7SetFileEP8BMD_Fileii(&mModel, f, 1, -1); func_ov095_0213597c(((char *)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char *)this)); { unsigned char i = (unsigned char)((char *)this)[0x31e]; f = _ZN12MeshCollider8LoadFileER13SharedFilePtr(*(int*)(data_ov095_021374a4 + i*0xc)); _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - ((char *)this)+0x124, f, ((char *)this)+0x2ec, 0x1000, unk_08e, *(int*)(data_ov095_021374a8 + i*0xc)); + &mMeshCollider, f, &mClsnMat, 0x1000, mAngleY, *(int*)(data_ov095_021374a8 + i*0xc)); } - func_020393d4(((char *)this)+0x124, _ZN16MeshColliderBase22UpdatePosWithTransformERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); - func_020393c4(((char *)this)+0x124, func_ov095_02135e90); + func_020393d4(&mMeshCollider, _ZN16MeshColliderBase22UpdatePosWithTransformERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + func_020393c4(&mMeshCollider, func_ov095_02135e90); return 1; } diff --git a/src/_ZN9SeesawBob16CleanupResourcesEv.cpp b/src/_ZN9SeesawBob16CleanupResourcesEv.cpp index 7e137377d..fca4fea8e 100644 --- a/src/_ZN9SeesawBob16CleanupResourcesEv.cpp +++ b/src/_ZN9SeesawBob16CleanupResourcesEv.cpp @@ -9,8 +9,8 @@ int SeesawBob::CleanupResources() { - if(((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if(((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); ((SharedFilePtr *)(*(void**)(data_ov095_021374a0 + (unsigned char)((char *)this)[0x31e]*0xc)))->Release(); ((SharedFilePtr *)(*(void**)(data_ov095_021374a4 + (unsigned char)((char *)this)[0x31e]*0xc)))->Release(); return 1; diff --git a/src/_ZN9SeesawBob8BehaviorEv.cpp b/src/_ZN9SeesawBob8BehaviorEv.cpp index 2402e86b2..a7f213d3a 100644 --- a/src/_ZN9SeesawBob8BehaviorEv.cpp +++ b/src/_ZN9SeesawBob8BehaviorEv.cpp @@ -15,10 +15,10 @@ void _ZN8Platform19UpdateClsnPosAndRotEv(void* self); int SeesawBob::Behavior() { - int b = (int)((unk_0b0 & 8) != 0); + int b = (int)(((*(s32 *)&mFlags) & 8) != 0); if (b != 0) { - if (((MeshColliderBase *)((char*)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char*)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char*)&(*(u8 *)&mMeshCollider)))->Disable(); } return 1; } @@ -33,8 +33,8 @@ int SeesawBob::Behavior() unk_320, 3, 0x8b, ((char*)this) + 0x74, 0); } } - if (unk_08c > 0x2000) unk_08c = 0x2000; - if (unk_08c < -0x2000) unk_08c = -0x2000; + if (mAngleX > 0x2000) mAngleX = 0x2000; + if (mAngleX < -0x2000) mAngleX = -0x2000; func_ov095_0213597c(((char*)this)); if (_ZN8Platform13IsClsnInRangeE5Fix12IiES1_(((char*)this), 0, 0)) { _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); diff --git a/src/_ZN9ShipWater16CleanupResourcesEv.cpp b/src/_ZN9ShipWater16CleanupResourcesEv.cpp index d22861b57..fd9284c99 100644 --- a/src/_ZN9ShipWater16CleanupResourcesEv.cpp +++ b/src/_ZN9ShipWater16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int data_ov017_02111c88[]; int ShipWater::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(data_ov017_02111c88))->Release(); ((SharedFilePtr *)(data_ov017_02111c80))->Release(); diff --git a/src/_ZN9ShipWater8BehaviorEv.cpp b/src/_ZN9ShipWater8BehaviorEv.cpp index ca81473af..056b7732f 100644 --- a/src/_ZN9ShipWater8BehaviorEv.cpp +++ b/src/_ZN9ShipWater8BehaviorEv.cpp @@ -35,8 +35,8 @@ int ShipWater::Behavior() *q -= 0x5000; } } - unk_32c = 0x1000; - _ZN9Animation7AdvanceEv((char*)&mTextureTransformer); + (*(s32 *)((char *)&mTextureTransformer + 0xc)) = 0x1000; + _ZN9Animation7AdvanceEv((char*)&(*(u8 *)&mTextureTransformer)); _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); return 1; diff --git a/src/_ZN9TinyCover16CleanupResourcesEv.cpp b/src/_ZN9TinyCover16CleanupResourcesEv.cpp index 85c9ab3b4..77ac34ec1 100644 --- a/src/_ZN9TinyCover16CleanupResourcesEv.cpp +++ b/src/_ZN9TinyCover16CleanupResourcesEv.cpp @@ -10,8 +10,8 @@ extern int data_ov033_021124f0[]; int TinyCover::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(data_ov033_021124f0))->Release(); ((SharedFilePtr *)(data_ov033_021124e8))->Release(); diff --git a/src/_ZN9TowerStep13InitResourcesEv.cpp b/src/_ZN9TowerStep13InitResourcesEv.cpp index a5ef121d0..0718aa4ea 100644 --- a/src/_ZN9TowerStep13InitResourcesEv.cpp +++ b/src/_ZN9TowerStep13InitResourcesEv.cpp @@ -24,8 +24,8 @@ int TowerStep::InitResources() _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); f = _ZN12MeshCollider8LoadFileER13SharedFilePtr(&data_ov015_02114a84); _ZN18MovingMeshCollider7SetFileEP8KCL_FileRK9Matrix4x35Fix12IiEsR10CLPS_Block( - ((char*)this) + 0x124, f, ((char*)this) + 0x2ec, 0x199, unk_08e, &data_ov015_02113654); - func_020393d4((int*)((char*)&mMeshCollider), (void*)&_ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); + ((char*)this) + 0x124, f, ((char*)this) + 0x2ec, 0x199, mAngleY, &data_ov015_02113654); + func_020393d4((int*)((char*)&(*(u8 *)&mMeshCollider)), (void*)&_ZN16MeshColliderBase16UpdatePosAndAngsERS_P5ActorR10ClsnResultR7Vector3P10Vector3_16S8_); unk_31e = 0x3c; return 1; } diff --git a/src/_ZN9TowerStep16CleanupResourcesEv.cpp b/src/_ZN9TowerStep16CleanupResourcesEv.cpp index 5b9950693..854da9fd1 100644 --- a/src/_ZN9TowerStep16CleanupResourcesEv.cpp +++ b/src/_ZN9TowerStep16CleanupResourcesEv.cpp @@ -11,8 +11,8 @@ extern int TowerStep_ModelFile[]; int TowerStep::CleanupResources() { - if (((MeshColliderBase *)((char *)&mMeshCollider))->IsEnabled()) { - ((MeshColliderBase *)((char *)&mMeshCollider))->Disable(); + if (((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->IsEnabled()) { + ((MeshColliderBase *)((char *)&(*(u8 *)&mMeshCollider)))->Disable(); } ((SharedFilePtr *)(TowerStep_ModelFile))->Release(); ((SharedFilePtr *)(TowerStep_ClsnFile))->Release(); diff --git a/src/_ZN9TowerStep8BehaviorEv.cpp b/src/_ZN9TowerStep8BehaviorEv.cpp index 14e6aef52..9c46fd986 100644 --- a/src/_ZN9TowerStep8BehaviorEv.cpp +++ b/src/_ZN9TowerStep8BehaviorEv.cpp @@ -16,12 +16,12 @@ int TowerStep::Behavior() if (DecIfAbove0_Byte((char*)&unk_31e) == 0) { short* p = (short*)(((int)((char*)this) + 0x94)); *p = *p + 0x100; - unk_08e = unk_094; - unk_320 = _ZN5Sound8PlayLongEjjjRK7Vector3s(unk_320, 3, 0x88, (void*)((char*)&unk_074), 0); - if ((unk_094 & 0x7fff) == 0) unk_31e = 0x3c; + mAngleY = mPrevAngleY; + unk_320 = _ZN5Sound8PlayLongEjjjRK7Vector3s(unk_320, 3, 0x88, (void*)((char*)&mCamSpacePosX), 0); + if ((mPrevAngleY & 0x7fff) == 0) unk_31e = 0x3c; } _ZN8Platform21UpdateModelPosAndRotYEv(((char*)this)); - func_020393a4((int*)((char*)&mMeshCollider), 0x320000); + func_020393a4((int*)((char*)&(*(u8 *)&mMeshCollider)), 0x320000); if (_ZN8Platform13IsClsnInRangeE5Fix12IiES1_(((char*)this), 0x320000, 0)) _ZN8Platform19UpdateClsnPosAndRotEv(((char*)this)); return 1; diff --git a/src/__sinit_020750b8.c b/src/__sinit_020750b8.c index 0d67cdabc..f8e04271e 100644 --- a/src/__sinit_020750b8.c +++ b/src/__sinit_020750b8.c @@ -1,5 +1,5 @@ extern void func_020731dc(void*, void*, void*); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern int data_020a0ebc[]; extern int data_020a0eb0[]; @@ -8,5 +8,5 @@ void __sinit_020750b8(void) data_020a0ebc[0] = 0; data_020a0ebc[1] = 0; data_020a0ebc[2] = 0; - func_020731dc(data_020a0ebc, (void*)&func_020072c0, data_020a0eb0); + func_020731dc(data_020a0ebc, (void*)&_ZN7Vector3D1Ev, data_020a0eb0); } diff --git a/src/__sinit_0207511c.c b/src/__sinit_0207511c.c index e6bba2834..f92938843 100644 --- a/src/__sinit_0207511c.c +++ b/src/__sinit_0207511c.c @@ -1,11 +1,11 @@ extern void func_020731dc(); extern short data_020a0edc[]; -extern int func_02011508[]; +extern int _ZN8Vector3sD1Ev[]; extern int data_020a0ee4[]; void __sinit_0207511c(void) { data_020a0edc[0] = 0; data_020a0edc[1] = 0; data_020a0edc[2] = 0; - func_020731dc(data_020a0edc, func_02011508, data_020a0ee4); + func_020731dc(data_020a0edc, _ZN8Vector3sD1Ev, data_020a0ee4); } diff --git a/src/__sinit_ov002_02100f84.c b/src/__sinit_ov002_02100f84.c index b7a8c67de..c0f7c695c 100644 --- a/src/__sinit_ov002_02100f84.c +++ b/src/__sinit_ov002_02100f84.c @@ -1,5 +1,5 @@ extern void func_020731dc(void* a, void* b, void** node); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern int data_ov002_0210ddd0[3]; extern int data_ov002_0210dddc[3]; @@ -16,7 +16,7 @@ void __sinit_ov002_02100f84(void) { data_ov002_0210ddd0[0] = 0; data_ov002_0210ddd0[1] = 0x190000; data_ov002_0210ddd0[2] = 0x12c000; - func_020731dc(data_ov002_0210ddd0, (void*)func_020072c0, &data_ov002_0210ddac); + func_020731dc(data_ov002_0210ddd0, (void*)_ZN7Vector3D1Ev, &data_ov002_0210ddac); { int *p = (int *)(((int)data_ov002_0210dddc) & 0xFFFFFFFFFFFFFFFFll); @@ -24,14 +24,14 @@ void __sinit_ov002_02100f84(void) { p[0] = 0; p[1] = -k; p[2] = 0x12c000; - func_020731dc(p, (void*)func_020072c0, &data_ov002_0210ddb8); + func_020731dc(p, (void*)_ZN7Vector3D1Ev, &data_ov002_0210ddb8); } { int *p = (int *)(((int)data_ov002_0210dde8) & 0xFFFFFFFFFFFFFFFFll); p[0] = 0x190000; p[1] = 0; p[2] = 0x12c000; - func_020731dc(p, (void*)func_020072c0, &data_ov002_0210ddc4); + func_020731dc(p, (void*)_ZN7Vector3D1Ev, &data_ov002_0210ddc4); } { int *p = (int *)(((int)data_ov002_0210ddf4) & 0xFFFFFFFFFFFFFFFFll); @@ -39,6 +39,6 @@ void __sinit_ov002_02100f84(void) { p[0] = -k; p[1] = 0; p[2] = 0x12c000; - func_020731dc(p, (void*)func_020072c0, &data_ov002_0210dda0); + func_020731dc(p, (void*)_ZN7Vector3D1Ev, &data_ov002_0210dda0); } } diff --git a/src/__sinit_ov002_0210804c.c b/src/__sinit_ov002_0210804c.c index 233e4f7eb..97c210521 100644 --- a/src/__sinit_ov002_0210804c.c +++ b/src/__sinit_ov002_0210804c.c @@ -1,11 +1,11 @@ extern void func_020731dc(void*, void*, void*); extern int data_ov002_0211116c[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int data_ov002_02111160[]; void __sinit_ov002_0210804c(void) { *(unsigned int*)data_ov002_0211116c = 0x80000; *(unsigned int*)((char*)data_ov002_0211116c + 4) = 0; *(unsigned int*)((char*)data_ov002_0211116c + 8) = 0x60000; - func_020731dc(data_ov002_0211116c, func_020072c0, data_ov002_02111160); + func_020731dc(data_ov002_0211116c, _ZN7Vector3D1Ev, data_ov002_02111160); } diff --git a/src/__sinit_ov006_0212f6b4.c b/src/__sinit_ov006_0212f6b4.c index b152feaf3..f3cd4e5d7 100644 --- a/src/__sinit_ov006_0212f6b4.c +++ b/src/__sinit_ov006_0212f6b4.c @@ -3,7 +3,7 @@ extern void func_020731dc(void*, void*, void*); extern void _ZN13SharedFilePtr9ConstructEj(void*, int); extern void func_02017a0c(void); extern void SharedFilePtr_Destruct_Anim(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern int data_ov006_021405f8[]; extern int data_ov006_021406ac[]; @@ -130,14 +130,14 @@ void __sinit_ov006_0212f6b4(void) data_ov006_02140778.x = (unsigned int)-0x50000; data_ov006_02140778.y = 0x100000; data_ov006_02140778.z = 0; - func_020731dc(&data_ov006_02140778, (void*)&func_020072c0, data_ov006_02140640); + func_020731dc(&data_ov006_02140778, (void*)&_ZN7Vector3D1Ev, data_ov006_02140640); { unsigned int *p = (unsigned int*)&data_ov006_02140784; p[0] = (unsigned int)-0x30000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_0214064c); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_0214064c); } { @@ -145,7 +145,7 @@ void __sinit_ov006_0212f6b4(void) p[0] = 0x10000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_02140658); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_02140658); } { @@ -153,7 +153,7 @@ void __sinit_ov006_0212f6b4(void) p[0] = 0x10000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_02140664); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_02140664); } { @@ -161,7 +161,7 @@ void __sinit_ov006_0212f6b4(void) p[0] = 0x30000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_02140670); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_02140670); } { @@ -169,7 +169,7 @@ void __sinit_ov006_0212f6b4(void) p[0] = 0x50000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_0214067c); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_0214067c); } data_ov006_021405b4 = data_ov006_0212e010; @@ -182,14 +182,14 @@ void __sinit_ov006_0212f6b4(void) data_ov006_021407c0.x = (unsigned int)-0x50000; data_ov006_021407c0.y = 0x100000; data_ov006_021407c0.z = 0; - func_020731dc(&data_ov006_021407c0, (void*)&func_020072c0, data_ov006_02140688); + func_020731dc(&data_ov006_021407c0, (void*)&_ZN7Vector3D1Ev, data_ov006_02140688); { unsigned int *p = (unsigned int*)&data_ov006_021407cc; p[0] = (unsigned int)-0x30000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_02140694); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_02140694); } { @@ -197,7 +197,7 @@ void __sinit_ov006_0212f6b4(void) p[0] = 0x10000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_021406a0); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_021406a0); } { @@ -205,7 +205,7 @@ void __sinit_ov006_0212f6b4(void) p[0] = 0x10000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_021406b8); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_021406b8); } { @@ -213,7 +213,7 @@ void __sinit_ov006_0212f6b4(void) p[0] = 0x30000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_021406dc); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_021406dc); } { @@ -221,6 +221,6 @@ void __sinit_ov006_0212f6b4(void) p[0] = 0x50000; p[1] = 0x100000; p[2] = 0; - func_020731dc(p, (void*)&func_020072c0, data_ov006_02140700); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, data_ov006_02140700); } } diff --git a/src/__sinit_ov009_02112524.c b/src/__sinit_ov009_02112524.c index cf0e1f856..152fb1c02 100644 --- a/src/__sinit_ov009_02112524.c +++ b/src/__sinit_ov009_02112524.c @@ -3,7 +3,7 @@ extern void func_02017b4c(void*, int); extern void func_020731dc(void*, void*, void*); extern int func_02017ab4[]; extern int SharedFilePtr_Destruct_Clsn[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int data_ov009_02113c68[]; extern int data_ov009_02113c70[]; extern int data_ov009_02113c78[]; @@ -60,143 +60,143 @@ void __sinit_ov009_02112524(void) *(unsigned int*)data_ov009_02113d8c = 0xfe94e000; *(unsigned int*)((char*)data_ov009_02113d8c + 4) = (unsigned int)-0x5a000; *(unsigned int*)((char*)data_ov009_02113d8c + 8) = 0xff60a000; - func_020731dc(data_ov009_02113d8c, func_020072c0, data_ov009_02113d74); + func_020731dc(data_ov009_02113d8c, _ZN7Vector3D1Ev, data_ov009_02113d74); { unsigned int *p = (unsigned int*)data_ov009_02113d98; p[0] = 0xfea20000; p[1] = (unsigned int)-0x5a000; p[2] = 0xff52e000; - func_020731dc(p, func_020072c0, data_ov009_02113d80); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113d80); } { unsigned int *p = (unsigned int*)data_ov009_02113da4; p[0] = (unsigned int)-0x1540000; p[1] = (unsigned int)-0x5a000; p[2] = 0xff43e000; - func_020731dc(p, func_020072c0, data_ov009_02113d08); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113d08); } { unsigned int *p = (unsigned int*)data_ov009_02113db0; p[0] = 0xfeb56000; p[1] = (unsigned int)-0x5a000; p[2] = 0xff344000; - func_020731dc(p, func_020072c0, data_ov009_02113d14); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113d14); } { unsigned int *p = (unsigned int*)data_ov009_02113dbc; p[0] = 0xfebb0000; p[1] = (unsigned int)-0x5a000; p[2] = 0xff236000; - func_020731dc(p, func_020072c0, data_ov009_02113d5c); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113d5c); } { unsigned int *p = (unsigned int*)data_ov009_02113dc8; p[0] = 0xfebe2000; p[1] = (unsigned int)-0x5a000; p[2] = 0xff114000; - func_020731dc(p, func_020072c0, data_ov009_02113d50); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113d50); } { unsigned int *p = (unsigned int*)data_ov009_02113dd4; p[0] = 0xfebe2000; p[1] = (unsigned int)-0x5a000; p[2] = 0xfeff2000; - func_020731dc(p, func_020072c0, data_ov009_02113d44); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113d44); } { *(unsigned int*)((char*)data_ov009_02113e34 + 0) = 0xfead4000; *(unsigned int*)((char*)data_ov009_02113e34 + 4) = (unsigned int)-0x320000; *(unsigned int*)((char*)data_ov009_02113e34 + 8) = 0xff682000; - func_020731dc(data_ov009_02113e34, func_020072c0, data_ov009_02113d2c); + func_020731dc(data_ov009_02113e34, _ZN7Vector3D1Ev, data_ov009_02113d2c); } { unsigned int *p = (unsigned int*)data_ov009_02113e40; p[0] = 0xfebb0000; p[1] = (unsigned int)-0x320000; p[2] = 0xff5ba000; - func_020731dc(p, func_020072c0, data_ov009_02113d20); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113d20); } { unsigned int *p = (unsigned int*)data_ov009_02113e4c; p[0] = 0xfec5a000; p[1] = (unsigned int)-0x320000; p[2] = 0xff4d4000; - func_020731dc(p, func_020072c0, data_ov009_02113c90); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113c90); } { unsigned int *p = (unsigned int*)data_ov009_02113e58; p[0] = 0xfecdc000; p[1] = (unsigned int)-0x320000; p[2] = (unsigned int)-0xc30000; - func_020731dc(p, func_020072c0, data_ov009_02113c84); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113c84); } { unsigned int *p = (unsigned int*)data_ov009_02113e64; p[0] = 0xfed54000; p[1] = (unsigned int)-0x320000; p[2] = 0xff2cc000; - func_020731dc(p, func_020072c0, data_ov009_02113cfc); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113cfc); } { unsigned int *p = (unsigned int*)data_ov009_02113e70; p[0] = 0xfed54000; p[1] = (unsigned int)-0x320000; p[2] = 0xff25e000; - func_020731dc(p, func_020072c0, data_ov009_02113cf0); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113cf0); } { unsigned int *p = (unsigned int*)data_ov009_02113e7c; p[0] = 0xfed68000; p[1] = (unsigned int)-0x320000; p[2] = 0xff1aa000; - func_020731dc(p, func_020072c0, data_ov009_02113cb4); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113cb4); } { *(unsigned int*)((char*)data_ov009_02113de0 + 0) = 0xfeb2e000; *(unsigned int*)((char*)data_ov009_02113de0 + 4) = 0xffbd2000; *(unsigned int*)((char*)data_ov009_02113de0 + 8) = (unsigned int)-0x960000; - func_020731dc(data_ov009_02113de0, func_020072c0, data_ov009_02113ccc); + func_020731dc(data_ov009_02113de0, _ZN7Vector3D1Ev, data_ov009_02113ccc); } { unsigned int *p = (unsigned int*)data_ov009_02113dec; p[0] = 0xfebf6000; p[1] = 0xffbd2000; p[2] = 0xff5ce000; - func_020731dc(p, func_020072c0, data_ov009_02113cd8); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113cd8); } { unsigned int *p = (unsigned int*)data_ov009_02113df8; p[0] = 0xfec96000; p[1] = 0xffbd2000; p[2] = 0xff4e8000; - func_020731dc(p, func_020072c0, data_ov009_02113ce4); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113ce4); } { unsigned int *p = (unsigned int*)data_ov009_02113e04; p[0] = 0xfed0e000; p[1] = 0xffbd2000; p[2] = 0xff3ee000; - func_020731dc(p, func_020072c0, data_ov009_02113d68); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113d68); } { unsigned int *p = (unsigned int*)data_ov009_02113e10; p[0] = 0xfed7c000; p[1] = 0xffbd2000; p[2] = 0xff2f4000; - func_020731dc(p, func_020072c0, data_ov009_02113ca8); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113ca8); } { unsigned int *p = (unsigned int*)data_ov009_02113e1c; p[0] = 0xfed9a000; p[1] = 0xffbd2000; p[2] = 0xff1e6000; - func_020731dc(p, func_020072c0, data_ov009_02113d38); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113d38); } { unsigned int *p = (unsigned int*)data_ov009_02113e28; p[0] = 0xfed72000; p[1] = 0xffbd2000; p[2] = 0xff0ce000; - func_020731dc(p, func_020072c0, data_ov009_02113c9c); + func_020731dc(p, _ZN7Vector3D1Ev, data_ov009_02113c9c); } } diff --git a/src/__sinit_ov019_021127a4.c b/src/__sinit_ov019_021127a4.c index e8dcb9600..280d72fda 100644 --- a/src/__sinit_ov019_021127a4.c +++ b/src/__sinit_ov019_021127a4.c @@ -5,7 +5,7 @@ extern int SharedFilePtr_Construct_TexSeq(void*, int); extern void func_02017ab4(void); extern void SharedFilePtr_Destruct_Anim(void); extern void SharedFilePtr_Destruct_TexSeq(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void* data_ov019_02113498; extern void* data_ov019_021134dc; @@ -93,10 +93,10 @@ void __sinit_ov019_021127a4(void) data_ov019_021134e8.x = -25962657; data_ov019_021134e8.y = -23381572; data_ov019_021134e8.z = -26155537; - func_020731dc(&data_ov019_021134e8, (void*)&func_020072c0, (void**)&data_ov019_021134d0); + func_020731dc(&data_ov019_021134e8, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov019_021134d0); data_ov019_0211353c.x = -19464192; data_ov019_0211353c.y = 0x600000; data_ov019_0211353c.z = 0; - func_020731dc(&data_ov019_0211353c, (void*)&func_020072c0, (void**)&data_ov019_02113518); + func_020731dc(&data_ov019_0211353c, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov019_02113518); } diff --git a/src/__sinit_ov019_02112b14.c b/src/__sinit_ov019_02112b14.c index d8b153ff6..aad6c5d89 100644 --- a/src/__sinit_ov019_02112b14.c +++ b/src/__sinit_ov019_02112b14.c @@ -1,11 +1,11 @@ extern void func_020731dc(void*, void*, void*); extern int data_ov019_021135d8[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int data_ov019_021135cc[]; void __sinit_ov019_02112b14(void) { *(unsigned int*)data_ov019_021135d8 = 0xfed60000; *(unsigned int*)((char*)data_ov019_021135d8 + 4) = 0x700000; *(unsigned int*)((char*)data_ov019_021135d8 + 8) = (unsigned int)-0x200000; - func_020731dc(data_ov019_021135d8, func_020072c0, data_ov019_021135cc); + func_020731dc(data_ov019_021135d8, _ZN7Vector3D1Ev, data_ov019_021135cc); } diff --git a/src/__sinit_ov021_02113500.c b/src/__sinit_ov021_02113500.c index 8745e201a..0f30b2db2 100644 --- a/src/__sinit_ov021_02113500.c +++ b/src/__sinit_ov021_02113500.c @@ -3,7 +3,7 @@ extern void func_020731dc(void*, void*, void*); extern void func_02017b4c(); extern int func_02017ab4[]; extern int SharedFilePtr_Destruct_Clsn[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int data_ov021_021149a0[]; extern int data_ov021_021149a8[]; extern int data_ov021_021149b0[]; @@ -37,14 +37,14 @@ void __sinit_ov021_02113500(void) data_ov021_02114a20.x = 0; data_ov021_02114a20.y = 0x32000; data_ov021_02114a20.z = 0xc8000; - func_020731dc(&data_ov021_02114a20, func_020072c0, data_ov021_021149fc); + func_020731dc(&data_ov021_02114a20, _ZN7Vector3D1Ev, data_ov021_021149fc); { volatile V3* p = (volatile V3*)&data_ov021_02114a2c; p->x = 0; p->y = 0x32000; p->z = -0xc8000; } - func_020731dc(&data_ov021_02114a2c, func_020072c0, data_ov021_02114a08); + func_020731dc(&data_ov021_02114a2c, _ZN7Vector3D1Ev, data_ov021_02114a08); { volatile V3* p = (volatile V3*)&data_ov021_02114a38; p->x = 0xc8000; p->y = 0x32000; p->z = 0; } - func_020731dc(&data_ov021_02114a38, func_020072c0, data_ov021_021149d8); + func_020731dc(&data_ov021_02114a38, _ZN7Vector3D1Ev, data_ov021_021149d8); { volatile V3* p = (volatile V3*)&data_ov021_02114a44; p->x = -0xc8000; p->y = 0x32000; p->z = 0; } - func_020731dc(&data_ov021_02114a44, func_020072c0, data_ov021_021149cc); + func_020731dc(&data_ov021_02114a44, _ZN7Vector3D1Ev, data_ov021_021149cc); } diff --git a/src/__sinit_ov027_02112f70.c b/src/__sinit_ov027_02112f70.c index 0979b7369..5cc763c9f 100644 --- a/src/__sinit_ov027_02112f70.c +++ b/src/__sinit_ov027_02112f70.c @@ -1,11 +1,11 @@ extern void func_020731dc(void*, void*, void*); extern int data_ov027_02113d10[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int data_ov027_02113d04[]; void __sinit_ov027_02112f70(void) { *(unsigned int*)data_ov027_02113d10 = 0x27a52b; *(unsigned int*)((char*)data_ov027_02113d10 + 4) = 0xdf2000; *(unsigned int*)((char*)data_ov027_02113d10 + 8) = 0x2626bb; - func_020731dc(data_ov027_02113d10, func_020072c0, data_ov027_02113d04); + func_020731dc(data_ov027_02113d10, _ZN7Vector3D1Ev, data_ov027_02113d04); } diff --git a/src/__sinit_ov030_02114924.c b/src/__sinit_ov030_02114924.c index 6227d24c5..d5748692f 100644 --- a/src/__sinit_ov030_02114924.c +++ b/src/__sinit_ov030_02114924.c @@ -3,7 +3,7 @@ extern void func_020731dc(void*, void*, void**); extern int _ZN13SharedFilePtr9ConstructEj(void*, int); extern void func_02017ab4(void); extern void SharedFilePtr_Destruct_Anim(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void* data_ov030_02115d00; extern void* data_ov030_02115d28; @@ -116,26 +116,26 @@ void __sinit_ov030_02114924(void) *(unsigned int*)&data_ov030_02115ddc = 0x1c000; *(unsigned int*)((char*)&data_ov030_02115ddc + 4) = (unsigned int)-0x42000; *(unsigned int*)((char*)&data_ov030_02115ddc + 8) = 0x18000; - func_020731dc(&data_ov030_02115ddc, (void*)&func_020072c0, (void**)&data_ov030_02115d58); + func_020731dc(&data_ov030_02115ddc, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov030_02115d58); { unsigned int *p = (unsigned int*)&data_ov030_02115de8; p[0] = 0x1c000; p[1] = (unsigned int)-0x28000; p[2] = 0x28000; - func_020731dc(p, (void*)&func_020072c0, (void**)&data_ov030_02115d4c); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov030_02115d4c); } { unsigned int *p = (unsigned int*)&data_ov030_02115df4; p[0] = 0x2b000; p[1] = (unsigned int)-0x42000; p[2] = 0x18000; - func_020731dc(p, (void*)&func_020072c0, (void**)&data_ov030_02115d7c); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov030_02115d7c); } { unsigned int *p = (unsigned int*)&data_ov030_02115e00; p[0] = 0x30000; p[1] = (unsigned int)-0x1e000; p[2] = 0x1e000; - func_020731dc(p, (void*)&func_020072c0, (void**)&data_ov030_02115da0); + func_020731dc(p, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov030_02115da0); } } diff --git a/src/__sinit_ov062_0211cf30.c b/src/__sinit_ov062_0211cf30.c index 6f87d6fee..3e6290340 100644 --- a/src/__sinit_ov062_0211cf30.c +++ b/src/__sinit_ov062_0211cf30.c @@ -3,7 +3,7 @@ extern void func_020731dc(void*, void*, void**); extern int _ZN13SharedFilePtr9ConstructEj(void*, int); extern void func_02017ab4(void); extern void SharedFilePtr_Destruct_Anim(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void* data_ov062_0211ddf0; extern void* data_ov062_0211de10; @@ -66,13 +66,13 @@ void __sinit_ov062_0211cf30(void) data_ov062_0211df10.x = 0x2c000; data_ov062_0211df10.y = -0x14000; data_ov062_0211df10.z = -0x78000; - func_020731dc(&data_ov062_0211df10, (void*)&func_020072c0, (void**)&data_ov062_0211de58); + func_020731dc(&data_ov062_0211df10, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov062_0211de58); int* p_df1c = (int*)&data_ov062_0211df1c; *p_df1c = 0x44000; p_df1c[1] = -0x14000; p_df1c[2] = -0x78000; - func_020731dc(&data_ov062_0211df1c, (void*)&func_020072c0, (void**)&data_ov062_0211de64); + func_020731dc(&data_ov062_0211df1c, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov062_0211de64); data_ov062_0211ded0.a = data_ov062_0211d940; data_ov062_0211ded0.b = data_ov062_0211d938; diff --git a/src/__sinit_ov070_02122d80.cpp b/src/__sinit_ov070_02122d80.cpp index c1b6fab4b..b80e31185 100644 --- a/src/__sinit_ov070_02122d80.cpp +++ b/src/__sinit_ov070_02122d80.cpp @@ -18,7 +18,7 @@ extern char data_ov070_02123650[]; extern char func_02017ab4[]; extern char SharedFilePtr_Destruct_Anim[]; extern char SharedFilePtr_Destruct_TexSeq[]; -extern char func_020072c0[]; +extern char _ZN7Vector3D1Ev[]; extern char data_ov070_02123644[]; struct S2 { int w[2]; }; @@ -55,6 +55,6 @@ void __sinit_ov070_02122d80(void) { data_ov070_0212365c[0] = 0; data_ov070_0212365c[1] = -0x28000; data_ov070_0212365c[2] = 0; - func_020731dc(data_ov070_0212365c, func_020072c0, data_ov070_02123644); + func_020731dc(data_ov070_0212365c, _ZN7Vector3D1Ev, data_ov070_02123644); } } diff --git a/src/__sinit_ov071_02122a1c.c b/src/__sinit_ov071_02122a1c.c index 3b9ecb976..abab93408 100644 --- a/src/__sinit_ov071_02122a1c.c +++ b/src/__sinit_ov071_02122a1c.c @@ -1,11 +1,11 @@ extern void func_020731dc(void*, void*, void*); extern int data_ov071_021230b8[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int data_ov071_021230c4[]; void __sinit_ov071_02122a1c(void) { *(unsigned int*)data_ov071_021230b8 = 0; *(unsigned int*)((char*)data_ov071_021230b8 + 4) = (unsigned int)-0x19000; *(unsigned int*)((char*)data_ov071_021230b8 + 8) = 0; - func_020731dc(data_ov071_021230b8, func_020072c0, data_ov071_021230c4); + func_020731dc(data_ov071_021230b8, _ZN7Vector3D1Ev, data_ov071_021230c4); } diff --git a/src/__sinit_ov072_02122018.c b/src/__sinit_ov072_02122018.c index f0e228282..25ac95006 100644 --- a/src/__sinit_ov072_02122018.c +++ b/src/__sinit_ov072_02122018.c @@ -1,7 +1,7 @@ extern int func_02017acc(); extern void func_020731dc(); extern void func_02017ab4(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern char data_ov072_02122b20[]; extern char data_ov072_02122b28[]; @@ -60,9 +60,9 @@ void __sinit_ov072_02122018(void) data_ov072_02122b40[0] = -0xad0000; data_ov072_02122b40[1] = 0x290000; data_ov072_02122b40[2] = -0x9d0000; - func_020731dc(data_ov072_02122b40, &func_020072c0, data_ov072_02122b34); + func_020731dc(data_ov072_02122b40, &_ZN7Vector3D1Ev, data_ov072_02122b34); data_ov072_02122b58[0] = 0xfeffc000; data_ov072_02122b58[1] = 0xffa6f000; data_ov072_02122b58[2] = 0x6fe000; - func_020731dc(data_ov072_02122b58, &func_020072c0, data_ov072_02122b4c); + func_020731dc(data_ov072_02122b58, &_ZN7Vector3D1Ev, data_ov072_02122b4c); } diff --git a/src/__sinit_ov072_02122350.c b/src/__sinit_ov072_02122350.c index 36a0f6ab2..4c86c77a4 100644 --- a/src/__sinit_ov072_02122350.c +++ b/src/__sinit_ov072_02122350.c @@ -7,7 +7,7 @@ extern int data_ov072_02122c48[]; extern int data_ov072_02122c50[]; extern int func_02017ab4[]; extern int SharedFilePtr_Destruct_TexSeq[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int data_ov072_02122c88[]; extern int data_ov072_02122c7c[]; extern int data_ov072_02122c58[]; @@ -25,5 +25,5 @@ void __sinit_ov072_02122350(void) data_ov072_02122c70[new_var] = (new_var = 0); data_ov072_02122c70[1] = -0x50000; data_ov072_02122c70[2] = new_var; - func_020731dc(data_ov072_02122c70, func_020072c0, data_ov072_02122c64); + func_020731dc(data_ov072_02122c70, _ZN7Vector3D1Ev, data_ov072_02122c64); } diff --git a/src/__sinit_ov072_02122414.c b/src/__sinit_ov072_02122414.c index e2857ac93..fae06282a 100644 --- a/src/__sinit_ov072_02122414.c +++ b/src/__sinit_ov072_02122414.c @@ -3,7 +3,7 @@ extern void func_020731dc(void *, void *, void **); extern int _ZN13SharedFilePtr9ConstructEj(void *, int); extern void func_02017ab4(void); extern void SharedFilePtr_Destruct_Anim(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); typedef struct { int a, b; } S8; typedef struct { S8 a, b; } S16; @@ -81,27 +81,27 @@ void __sinit_ov072_02122414(void) data_ov072_02122d3c.x = 0x1c000; data_ov072_02122d3c.y = 0; data_ov072_02122d3c.z = 0x1e000; - func_020731dc(&data_ov072_02122d3c, (void *)&func_020072c0, (void **)&data_ov072_02122cd0); + func_020731dc(&data_ov072_02122d3c, (void *)&_ZN7Vector3D1Ev, (void **)&data_ov072_02122cd0); { unsigned int *p = (unsigned int *)&data_ov072_02122d48; p[0] = 0x1c000; p[1] = 0; p[2] = 0x1e000; - func_020731dc(p, (void *)&func_020072c0, (void **)&data_ov072_02122cdc); + func_020731dc(p, (void *)&_ZN7Vector3D1Ev, (void **)&data_ov072_02122cdc); } { unsigned int *p = (unsigned int *)&data_ov072_02122d54; p[0] = 0x2b000; p[1] = 0; p[2] = 0x1e000; - func_020731dc(p, (void *)&func_020072c0, (void **)&data_ov072_02122ce8); + func_020731dc(p, (void *)&_ZN7Vector3D1Ev, (void **)&data_ov072_02122ce8); } { unsigned int *p = (unsigned int *)&data_ov072_02122d60; p[0] = 0x30000; p[1] = 0; p[2] = 0x32000; - func_020731dc(p, (void *)&func_020072c0, (void **)&data_ov072_02122cf4); + func_020731dc(p, (void *)&_ZN7Vector3D1Ev, (void **)&data_ov072_02122cf4); } } diff --git a/src/__sinit_ov077_02127240.c b/src/__sinit_ov077_02127240.c index 6afac5f53..52fb6d8ae 100644 --- a/src/__sinit_ov077_02127240.c +++ b/src/__sinit_ov077_02127240.c @@ -5,7 +5,7 @@ extern int SharedFilePtr_Construct_TexSeq(void*, int); extern void func_02017ab4(void); extern void SharedFilePtr_Destruct_Anim(void); extern void SharedFilePtr_Destruct_TexSeq(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void* data_ov077_02127b50; extern void* data_ov077_02127b94; @@ -70,5 +70,5 @@ void __sinit_ov077_02127240(void) data_ov077_02127b88.x = 0; data_ov077_02127b88.y = -0x1e000; data_ov077_02127b88.z = 0; - func_020731dc(&data_ov077_02127b88, (void*)&func_020072c0, (void**)&data_ov077_02127b7c); + func_020731dc(&data_ov077_02127b88, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov077_02127b7c); } diff --git a/src/__sinit_ov078_02126660.c b/src/__sinit_ov078_02126660.c index 76ebf2a11..3b19009d2 100644 --- a/src/__sinit_ov078_02126660.c +++ b/src/__sinit_ov078_02126660.c @@ -3,7 +3,7 @@ extern void func_020731dc(void*, void*, void**); extern int _ZN13SharedFilePtr9ConstructEj(void*, int); extern void func_02017ab4(void); extern void SharedFilePtr_Destruct_Anim(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void* data_ov078_02126f38; extern void* data_ov078_02126f48; @@ -128,7 +128,7 @@ void __sinit_ov078_02126660(void) data_ov078_0212711c.x = 0x2c000; data_ov078_0212711c.y = -0x19000; data_ov078_0212711c.z = 0x34000; - func_020731dc(&data_ov078_0212711c, (void*)&func_020072c0, (void**)&data_ov078_02126fe4); + func_020731dc(&data_ov078_0212711c, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov078_02126fe4); { int *p = (int *)&data_ov078_02127128; @@ -136,7 +136,7 @@ void __sinit_ov078_02126660(void) p[1] = -0x19000; p[2] = 0x34000; } - func_020731dc(&data_ov078_02127128, (void*)&func_020072c0, (void**)&data_ov078_02126ff0); + func_020731dc(&data_ov078_02127128, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov078_02126ff0); data_ov078_0212710c.lo = data_ov078_02126d78; data_ov078_0212710c.hi = data_ov078_02126d40; diff --git a/src/__sinit_ov081_021284f0.c b/src/__sinit_ov081_021284f0.c index cd4d322b7..c6d340233 100644 --- a/src/__sinit_ov081_021284f0.c +++ b/src/__sinit_ov081_021284f0.c @@ -3,7 +3,7 @@ extern void func_020731dc(); extern void _ZN13SharedFilePtr9ConstructEj(); extern void func_02017ab4(); extern void SharedFilePtr_Destruct_Anim(); -extern void func_020072c0(); +extern void _ZN7Vector3D1Ev(); typedef struct { int a, b; } S8; @@ -65,5 +65,5 @@ void __sinit_ov081_021284f0(void) data_ov081_02128ef8.a = 0; data_ov081_02128ef8.b = 0x2000; data_ov081_02128ef8.c = 0; - func_020731dc(&data_ov081_02128ef8, func_020072c0, &data_ov081_02128eec); + func_020731dc(&data_ov081_02128ef8, _ZN7Vector3D1Ev, &data_ov081_02128eec); } diff --git a/src/__sinit_ov085_0212f5ec.c b/src/__sinit_ov085_0212f5ec.c index 98f11025f..219a6c771 100644 --- a/src/__sinit_ov085_0212f5ec.c +++ b/src/__sinit_ov085_0212f5ec.c @@ -3,7 +3,7 @@ extern void func_020731dc(void*, void*, void**); extern int _ZN13SharedFilePtr9ConstructEj(void*, int); extern void func_02017ab4(void); extern void SharedFilePtr_Destruct_Anim(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern int _ZN8SaveData22NumGlowingRabbitsFoundEv(void); extern void* data_ov085_021305d8; @@ -74,16 +74,16 @@ void __sinit_ov085_0212f5ec(void) data_ov085_021306ec.x = 0x1c000; data_ov085_021306ec.y = -0x2a000; data_ov085_021306ec.z = 0x18000; - func_020731dc(&data_ov085_021306ec, (void*)&func_020072c0, (void**)&data_ov085_0213063c); + func_020731dc(&data_ov085_021306ec, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov085_0213063c); { volatile V3* p = (volatile V3*)&data_ov085_021306f8; p->x = 0x1c000; p->y = -0x14000; p->z = 0x32000; } - func_020731dc(&data_ov085_021306f8, (void*)&func_020072c0, (void**)&data_ov085_02130648); + func_020731dc(&data_ov085_021306f8, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov085_02130648); { volatile V3* p = (volatile V3*)&data_ov085_02130704; p->x = 0x2b000; p->y = -0x2a000; p->z = 0x18000; } - func_020731dc(&data_ov085_02130704, (void*)&func_020072c0, (void**)&data_ov085_02130654); + func_020731dc(&data_ov085_02130704, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov085_02130654); { volatile V3* p = (volatile V3*)&data_ov085_02130710; p->x = 0x30000; p->y = -0xa000; p->z = 0x32000; } - func_020731dc(&data_ov085_02130710, (void*)&func_020072c0, (void**)&data_ov085_02130660); + func_020731dc(&data_ov085_02130710, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov085_02130660); data_ov085_021306cc.a = data_ov085_02130074; data_ov085_021306cc.b = data_ov085_02130044; diff --git a/src/__sinit_ov085_0212fa40.c b/src/__sinit_ov085_0212fa40.c index 7c4c8ed86..9998013f7 100644 --- a/src/__sinit_ov085_0212fa40.c +++ b/src/__sinit_ov085_0212fa40.c @@ -5,7 +5,7 @@ extern int SharedFilePtr_Construct_TexSeq(void*, int); extern void func_02017ab4(void); extern void SharedFilePtr_Destruct_Anim(void); extern void SharedFilePtr_Destruct_TexSeq(void); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void* data_ov085_0213074c; extern void* data_ov085_02130744; @@ -93,8 +93,8 @@ void __sinit_ov085_0212fa40(void) data_ov085_02130840.a = -0x640000; data_ov085_02130840.b = 0x378000; data_ov085_02130840.c = 0x1670000; - func_020731dc(&data_ov085_02130840, (void*)&func_020072c0, (void**)&data_ov085_02130754); + func_020731dc(&data_ov085_02130840, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov085_02130754); { volatile S12* p = (volatile S12*)&data_ov085_0213084c; p->a = 0; p->b = 0x4d8000; p->c = -0x104000; } - func_020731dc(&data_ov085_0213084c, (void*)&func_020072c0, (void**)&data_ov085_02130760); + func_020731dc(&data_ov085_0213084c, (void*)&_ZN7Vector3D1Ev, (void**)&data_ov085_02130760); } diff --git a/src/__sinit_ov102_0214de70.c b/src/__sinit_ov102_0214de70.c index 8bb9f8dbd..b9b113e2c 100644 --- a/src/__sinit_ov102_0214de70.c +++ b/src/__sinit_ov102_0214de70.c @@ -1,7 +1,7 @@ extern void _ZN13SharedFilePtr9ConstructEj(); extern void func_020731dc(void*, void*, void*); extern void SharedFilePtr_Destruct_Anim(); -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; extern int data_ov102_0214e9c0[]; extern int data_ov102_0214e9c8[]; extern int data_ov102_0214e9d0[]; @@ -27,14 +27,14 @@ void __sinit_ov102_0214de70(void) data_ov102_0214ea18.x = 0x1c000; data_ov102_0214ea18.y = -0x14000; data_ov102_0214ea18.z = 0x28000; - func_020731dc(&data_ov102_0214ea18, func_020072c0, data_ov102_0214ea0c); + func_020731dc(&data_ov102_0214ea18, _ZN7Vector3D1Ev, data_ov102_0214ea0c); { volatile V3* p = (volatile V3*)&data_ov102_0214ea24; p->x = 0x1c000; p->y = -0x14000; p->z = 0x3c000; } - func_020731dc(&data_ov102_0214ea24, func_020072c0, data_ov102_0214e9f4); + func_020731dc(&data_ov102_0214ea24, _ZN7Vector3D1Ev, data_ov102_0214e9f4); { volatile V3* p = (volatile V3*)&data_ov102_0214ea30; p->x = 0x2b000; p->y = -0xa000; p->z = -0x14000; } - func_020731dc(&data_ov102_0214ea30, func_020072c0, data_ov102_0214ea00); + func_020731dc(&data_ov102_0214ea30, _ZN7Vector3D1Ev, data_ov102_0214ea00); { volatile V3* p = (volatile V3*)&data_ov102_0214ea3c; p->x = 0x30000; p->y = -0x1e000; p->z = 0x3c000; } - func_020731dc(&data_ov102_0214ea3c, func_020072c0, data_ov102_0214e9e8); + func_020731dc(&data_ov102_0214ea3c, _ZN7Vector3D1Ev, data_ov102_0214e9e8); } diff --git a/src/func_020072c0.c b/src/func_020072c0.c deleted file mode 100644 index de022185f..000000000 --- a/src/func_020072c0.c +++ /dev/null @@ -1,3 +0,0 @@ -void func_020072c0(void) -{ -} diff --git a/src/func_02011508.c b/src/func_02011508.c deleted file mode 100644 index c411af582..000000000 --- a/src/func_02011508.c +++ /dev/null @@ -1,3 +0,0 @@ -void func_02011508(void) -{ -} diff --git a/src/func_ov002_020c44c4.c b/src/func_ov002_020c44c4.c index b0965234e..6ecca6062 100644 --- a/src/func_ov002_020c44c4.c +++ b/src/func_ov002_020c44c4.c @@ -9,7 +9,7 @@ extern u8 data_0209f2d8; extern int data_0209caa0[]; extern s8 data_0209f2f8; extern u8 data_0209f264; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void func_020731dc(int a, int b, void** node); extern void Vec3_RotateYAndTranslate(int* out, int* in, short angle, int* src); @@ -58,7 +58,7 @@ int func_ov002_020c44c4(char* self) data_ov002_0210f3b0.x = 0; data_ov002_0210f3b0.y = 0x96000; data_ov002_0210f3b0.z = 0x64000; - func_020731dc((int)&data_ov002_0210f3b0, (int)func_020072c0, &data_ov002_0210f350); + func_020731dc((int)&data_ov002_0210f3b0, (int)_ZN7Vector3D1Ev, &data_ov002_0210f350); data_ov002_0210e14c |= 1; } Vec3_RotateYAndTranslate((int*)&pos, (int*)(self + 0x5c), *(s16*)(self + 0x8e), (int*)&data_ov002_0210f3b0); diff --git a/src/func_ov002_020c8a4c.cpp b/src/func_ov002_020c8a4c.cpp index e2ffc7c0e..b26d1f415 100644 --- a/src/func_ov002_020c8a4c.cpp +++ b/src/func_ov002_020c8a4c.cpp @@ -9,7 +9,11 @@ struct Player { unsigned int SetAnim(unsigned int, int, int, unsigned int); }; extern "C" short Vec3_HorzAngle(const Vector3*, const Vector3*); extern "C" void func_020731dc(void*, void*, void*); extern "C" void Vec3_RotateYAndTranslate(Vector3*, const Vector3*, int, const Vector3*); -extern void func_020072c0(void); +/* extern "C": this is the ROM symbol's own name. A bare `extern` in a //cpp file + makes the compiler mangle it AGAIN, into _Z15_ZN7Vector3D1Evv, which exists + nowhere -- and the byte gate cannot see it, because relocated words are + wildcarded. Only check_references does. */ +extern "C" void _ZN7Vector3D1Ev(void); extern "C" int func_ov002_020c8a4c(char* self); int func_ov002_020c8a4c(char* self) { @@ -25,7 +29,7 @@ int func_ov002_020c8a4c(char* self) { data_ov002_0210f8cc[0] = 0; data_ov002_0210f8cc[1] = 0; data_ov002_0210f8cc[2] = 0x12c000; - func_020731dc(data_ov002_0210f8cc, (void*)func_020072c0, &data_ov002_0210f89c); + func_020731dc(data_ov002_0210f8cc, (void*)_ZN7Vector3D1Ev, &data_ov002_0210f89c); data_ov002_0210e150 |= 1; } Vec3_RotateYAndTranslate((Vector3*)(self + 0x744), (Vector3*)(self + 0x750), *(short*)(self + 0x69e), (Vector3*)data_ov002_0210f8cc); diff --git a/src/func_ov002_020c8b78.cpp b/src/func_ov002_020c8b78.cpp index 6d929a73d..e09128acb 100644 --- a/src/func_ov002_020c8b78.cpp +++ b/src/func_ov002_020c8b78.cpp @@ -20,7 +20,7 @@ extern "C" { extern int _ZN6Player12FinishedAnimEv(Player *); } extern "C" void func_020731dc(void *a, void *b, void *node); -extern "C" void func_020072c0(void); +extern "C" void _ZN7Vector3D1Ev(void); extern "C" { extern void Vec3_RotateYAndTranslate(Vector3 *, void *, int, void *); extern void _ZN6Player11ShowMessageER9ActorBasejPK7Vector3hh(Player *, ActorBase &, unsigned int, Vector3 const *, unsigned int, unsigned int); @@ -45,7 +45,7 @@ extern "C" int func_ov002_020c8b78(char *self) { data_ov002_0210f824[0] = 0; data_ov002_0210f824[1] = 0x96000; data_ov002_0210f824[2] = 0x64000; - func_020731dc(data_ov002_0210f824, (void *)func_020072c0, data_ov002_0210f7f4); + func_020731dc(data_ov002_0210f824, (void *)_ZN7Vector3D1Ev, data_ov002_0210f7f4); data_ov002_0210e154 |= 1; } Vec3_RotateYAndTranslate(&v, self + 0x5c, *(s16 *)(self + 0x8e), data_ov002_0210f824); diff --git a/src/func_ov002_020f6778.cpp b/src/func_ov002_020f6778.cpp index aca84bdb0..cdd85a415 100644 --- a/src/func_ov002_020f6778.cpp +++ b/src/func_ov002_020f6778.cpp @@ -3,7 +3,7 @@ extern "C" { extern int data_ov002_0210bcc4[]; extern int data_ov002_0210bce8[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; void _ZN9ModelAnimD2Ev(void*); void __destroy_arr(void*, int, int, void*); void _ZN6Memory16operator_delete2EPv(void*); @@ -30,7 +30,7 @@ void* func_ov002_020f6778(char* c){ } } _ZN9ModelAnimD2Ev(c); - __destroy_arr(c+0x64, 1, 0xc, (void*)func_020072c0); + __destroy_arr(c+0x64, 1, 0xc, (void*)_ZN7Vector3D1Ev); _ZN6Memory16operator_delete2EPv(c); return c; } diff --git a/src/func_ov002_020f6870.cpp b/src/func_ov002_020f6870.cpp index 18b316d2f..aa74456d4 100644 --- a/src/func_ov002_020f6870.cpp +++ b/src/func_ov002_020f6870.cpp @@ -3,7 +3,7 @@ extern "C" { extern int data_ov002_0210bcc4[]; extern int data_ov002_0210bce8[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; void _ZN9ModelAnimD2Ev(void*); void __destroy_arr(void*, int, int, void*); typedef void (*VFN)(void*); @@ -29,7 +29,7 @@ void* func_ov002_020f6870(char* c){ } } _ZN9ModelAnimD2Ev(c); - __destroy_arr(c+0x64, 1, 0xc, (void*)func_020072c0); + __destroy_arr(c+0x64, 1, 0xc, (void*)_ZN7Vector3D1Ev); return c; } } diff --git a/src/func_ov002_020f69a8.cpp b/src/func_ov002_020f69a8.cpp index 24fa4b746..721f80b40 100644 --- a/src/func_ov002_020f69a8.cpp +++ b/src/func_ov002_020f69a8.cpp @@ -2,7 +2,7 @@ #include "SharedFilePtr.h" extern "C" { extern int data_ov002_0210bae4[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; void _ZN5ModelD2Ev(void*); void __destroy_arr(void*, int, int, void*); void _ZN6Memory16operator_delete2EPv(void*); @@ -14,7 +14,7 @@ void* func_ov002_020f69a8(char* c){ ((SharedFilePtr *)(p))->Release(); } _ZN5ModelD2Ev(c); - __destroy_arr(c+0x50, 1, 0xc, (void*)func_020072c0); + __destroy_arr(c+0x50, 1, 0xc, (void*)_ZN7Vector3D1Ev); _ZN6Memory16operator_delete2EPv(c); return c; } diff --git a/src/func_ov002_020f6a00.cpp b/src/func_ov002_020f6a00.cpp index b724bbd79..ab5113c64 100644 --- a/src/func_ov002_020f6a00.cpp +++ b/src/func_ov002_020f6a00.cpp @@ -2,7 +2,7 @@ #include "SharedFilePtr.h" extern "C" { extern int data_ov002_0210bae4[]; -extern int func_020072c0[]; +extern int _ZN7Vector3D1Ev[]; void _ZN5ModelD2Ev(void*); void __destroy_arr(void*, int, int, void*); void* func_ov002_020f6a00(char* c){ @@ -13,7 +13,7 @@ void* func_ov002_020f6a00(char* c){ ((SharedFilePtr *)(p))->Release(); } _ZN5ModelD2Ev(c); - __destroy_arr(c+0x50, 1, 0xc, (void*)func_020072c0); + __destroy_arr(c+0x50, 1, 0xc, (void*)_ZN7Vector3D1Ev); return c; } } diff --git a/src/func_ov002_020f6a50.c b/src/func_ov002_020f6a50.c index 1d1d60ab3..57e236737 100644 --- a/src/func_ov002_020f6a50.c +++ b/src/func_ov002_020f6a50.c @@ -1,10 +1,10 @@ extern void func_020733a8(void* obj, int a, int b, void* cb1, void* cb2); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void func_0203d384(void); void* func_ov002_020f6a50(char* c) { - func_020733a8(c, 1, 0xc, (void*)func_0203d384, (void*)func_020072c0); + func_020733a8(c, 1, 0xc, (void*)func_0203d384, (void*)_ZN7Vector3D1Ev); *(int*)c = 0; *(int*)(c+4) = 0; *(int*)(c+8) = 0; diff --git a/src/func_ov002_020f6c60.c b/src/func_ov002_020f6c60.c index 86c4b9362..cd2b15d1d 100644 --- a/src/func_ov002_020f6c60.c +++ b/src/func_ov002_020f6c60.c @@ -18,7 +18,7 @@ extern char *data_0209f318; extern int data_ov002_0210b614; extern int data_ov002_02110b0c; extern int data_ov002_02110c20[]; -extern int func_020072c0; +extern int _ZN7Vector3D1Ev; extern int data_ov002_02110db8; extern int data_ov002_0210b958; extern int data_0209b41c; @@ -64,7 +64,7 @@ int func_ov002_020f6c60(void *arg0, void *arg1, int arg2, int arg3) data_ov002_02110c20[0] = 0xffdd6000; data_ov002_02110c20[1] = 0xbe4000; data_ov002_02110c20[2] = 0x2ae000; - func_020731dc((int) data_ov002_02110c20, (int) (&func_020072c0), (void **) (&data_ov002_02110db8)); + func_020731dc((int) data_ov002_02110c20, (int) (&_ZN7Vector3D1Ev), (void **) (&data_ov002_02110db8)); data_ov002_02110b0c |= 1; } func_ov002_020f6f48(c, (Vec3 *) data_ov002_02110c20, 0x20); diff --git a/src/func_ov002_020f7538.c b/src/func_ov002_020f7538.c index 27027fec8..de4eb0be3 100644 --- a/src/func_ov002_020f7538.c +++ b/src/func_ov002_020f7538.c @@ -16,7 +16,7 @@ extern int data_ov002_02110b08; extern int data_ov002_02110df4[]; extern int data_ov002_02110e0c[]; extern int data_ov002_02110e18[]; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern int data_ov002_02110de8[]; extern int data_ov002_02110e00[]; extern int data_ov002_02110dac[]; @@ -42,21 +42,21 @@ int func_ov002_020f7538(char* c, unsigned char* arg1, int arg2) { data_ov002_02110df4[0] = 0x2800; data_ov002_02110df4[1] = 0xfffee900; data_ov002_02110df4[2] = -0x4200; - func_020731dc((int)data_ov002_02110df4, (int)func_020072c0, (void**)data_ov002_02110de8); + func_020731dc((int)data_ov002_02110df4, (int)_ZN7Vector3D1Ev, (void**)data_ov002_02110de8); data_ov002_02110b04 |= 1; } if (!(data_ov002_02110afc & 1)) { data_ov002_02110e0c[0] = 0x3300; data_ov002_02110e0c[1] = 0xfffee900; data_ov002_02110e0c[2] = -0x5e00; - func_020731dc((int)data_ov002_02110e0c, (int)func_020072c0, (void**)data_ov002_02110e00); + func_020731dc((int)data_ov002_02110e0c, (int)_ZN7Vector3D1Ev, (void**)data_ov002_02110e00); data_ov002_02110afc |= 1; } if (!(data_ov002_02110b08 & 1)) { data_ov002_02110e18[0] = 0x4c00; data_ov002_02110e18[1] = -0xf200; data_ov002_02110e18[2] = -0xff00; - func_020731dc((int)data_ov002_02110e18, (int)func_020072c0, (void**)data_ov002_02110dac); + func_020731dc((int)data_ov002_02110e18, (int)_ZN7Vector3D1Ev, (void**)data_ov002_02110dac); data_ov002_02110b08 |= 1; } diff --git a/src/func_ov006_020c3754.c b/src/func_ov006_020c3754.c index 221168392..1537e37b2 100644 --- a/src/func_ov006_020c3754.c +++ b/src/func_ov006_020c3754.c @@ -4,7 +4,7 @@ extern int data_ov006_021402f0[3]; extern int data_0209e650; extern int data_02092768[4]; extern void func_020731dc(void **node, int a, int b); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern int RandomIntInternal(int *seed); extern void func_0203cd80(void *q, int a); extern void Quaternion_FromVector3(void *out, void *p, int *in); @@ -17,7 +17,7 @@ void func_ov006_020c3754(int *r6, int *r5, int *r4) n[0] = 0; n[1] = 0x1000; n[2] = 0; - func_020731dc((void **)n, (int)func_020072c0, (int)&data_ov006_021402e4); + func_020731dc((void **)n, (int)_ZN7Vector3D1Ev, (int)&data_ov006_021402e4); data_ov006_021402e0 |= 1; } r6[0] = r5[0]; diff --git a/src/func_ov006_020c64e4.c b/src/func_ov006_020c64e4.c index 3a3a9aeeb..2ed546ee5 100644 --- a/src/func_ov006_020c64e4.c +++ b/src/func_ov006_020c64e4.c @@ -3,7 +3,7 @@ typedef struct { int a, b; } W2; extern void func_020731dc(int a, int b, void **node); extern void Vec3_Add(Vec3 *out, Vec3 *a, Vec3 *b); -extern int func_020072c0(void); +extern int _ZN7Vector3D1Ev(void); extern int data_ov006_0213af70[2]; extern int data_ov006_0213afc0[2]; @@ -39,14 +39,14 @@ void func_ov006_020c64e4(char *c) data_ov006_021403d0.x = -0x100000; data_ov006_021403d0.y = 0; data_ov006_021403d0.z = 0; - func_020731dc((int)&data_ov006_021403d0, (int)&func_020072c0, &data_ov006_021403c4); + func_020731dc((int)&data_ov006_021403d0, (int)&_ZN7Vector3D1Ev, &data_ov006_021403c4); data_ov006_02140300 |= 1; } if ((data_ov006_0214030c & 1) == 0) { data_ov006_021403e8.x = 0x100000; data_ov006_021403e8.y = 0; data_ov006_021403e8.z = 0; - func_020731dc((int)&data_ov006_021403e8, (int)&func_020072c0, &data_ov006_021403dc); + func_020731dc((int)&data_ov006_021403e8, (int)&_ZN7Vector3D1Ev, &data_ov006_021403dc); data_ov006_0214030c |= 1; } diff --git a/src/func_ov006_020c68f4.c b/src/func_ov006_020c68f4.c index adbaee0e2..5684331aa 100644 --- a/src/func_ov006_020c68f4.c +++ b/src/func_ov006_020c68f4.c @@ -3,7 +3,7 @@ typedef struct { int x, y, z, w; } Vec4; extern void func_020731dc(int a, int b, void **node); extern void AddVec3(Vec3 *a, Vec3 *b, Vec3 *c); -extern int func_020072c0(void); +extern int _ZN7Vector3D1Ev(void); extern int data_ov006_02140310; extern Vec3 data_ov006_02140394; @@ -20,14 +20,14 @@ void func_ov006_020c68f4(char* dst, char* src) data_ov006_02140394.x = -0x100000; data_ov006_02140394.y = 0; data_ov006_02140394.z = 0; - func_020731dc((int)&data_ov006_02140394, (int)&func_020072c0, (void**)&data_ov006_02140388); + func_020731dc((int)&data_ov006_02140394, (int)&_ZN7Vector3D1Ev, (void**)&data_ov006_02140388); data_ov006_02140310 |= 1; } if (!(data_ov006_02140320 & 1)) { data_ov006_021403ac.x = 0x100000; data_ov006_021403ac.y = 0; data_ov006_021403ac.z = 0; - func_020731dc((int)&data_ov006_021403ac, (int)&func_020072c0, (void**)&data_ov006_021403a0); + func_020731dc((int)&data_ov006_021403ac, (int)&_ZN7Vector3D1Ev, (void**)&data_ov006_021403a0); data_ov006_02140320 |= 1; } diff --git a/src/func_ov006_020c6ca4.c b/src/func_ov006_020c6ca4.c index 92bc459a4..b46822aec 100644 --- a/src/func_ov006_020c6ca4.c +++ b/src/func_ov006_020c6ca4.c @@ -3,7 +3,7 @@ typedef struct { int x, y, z, w; } Vec4; extern void func_020731dc(int a, int b, void **node); extern void AddVec3(Vec3 *a, Vec3 *b, Vec3 *c); -extern int func_020072c0(void); +extern int _ZN7Vector3D1Ev(void); extern int data_ov006_0214032c; extern Vec3 data_ov006_02140364; @@ -20,14 +20,14 @@ void func_ov006_020c6ca4(char* dst, char* src) data_ov006_02140364.x = -0x100000; data_ov006_02140364.y = 0; data_ov006_02140364.z = 0; - func_020731dc((int)&data_ov006_02140364, (int)&func_020072c0, (void**)&data_ov006_02140358); + func_020731dc((int)&data_ov006_02140364, (int)&_ZN7Vector3D1Ev, (void**)&data_ov006_02140358); data_ov006_0214032c |= 1; } if (!(data_ov006_02140318 & 1)) { data_ov006_0214037c.x = 0x100000; data_ov006_0214037c.y = 0; data_ov006_0214037c.z = 0; - func_020731dc((int)&data_ov006_0214037c, (int)&func_020072c0, (void**)&data_ov006_02140370); + func_020731dc((int)&data_ov006_0214037c, (int)&_ZN7Vector3D1Ev, (void**)&data_ov006_02140370); data_ov006_02140318 |= 1; } diff --git a/src/func_ov006_020cd864.c b/src/func_ov006_020cd864.c index c4c64d369..b992be25c 100644 --- a/src/func_ov006_020cd864.c +++ b/src/func_ov006_020cd864.c @@ -3,7 +3,7 @@ #include "decl_common.h" /* recovered: shared common types */ #include "common.h" -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void func_020731dc(int a, int b, void** node); @@ -15,14 +15,14 @@ void func_ov006_020cd864(char* arg) { data_ov006_02140938.x = 0; data_ov006_02140938.y = 0x1000; data_ov006_02140938.z = 0; - func_020731dc((int)&data_ov006_02140938, (int)func_020072c0, &data_ov006_02140920); + func_020731dc((int)&data_ov006_02140938, (int)_ZN7Vector3D1Ev, &data_ov006_02140920); data_ov006_02140820 |= 1; } if ((data_ov006_02140840 & 1) == 0) { data_ov006_02140884.x = 0; data_ov006_02140884.y = 0; data_ov006_02140884.z = 0x1000; - func_020731dc((int)&data_ov006_02140884, (int)func_020072c0, &data_ov006_0214086c); + func_020731dc((int)&data_ov006_02140884, (int)_ZN7Vector3D1Ev, &data_ov006_0214086c); data_ov006_02140840 |= 1; } func_0203cc28((int*)(arg + 0x38), 0x100); diff --git a/src/func_ov006_020cd9b0.c b/src/func_ov006_020cd9b0.c index 7357dffee..901a647bd 100644 --- a/src/func_ov006_020cd9b0.c +++ b/src/func_ov006_020cd9b0.c @@ -5,7 +5,7 @@ extern void func_0203ce80(Vec3* dst, Vec3* src); extern void func_0203cf00(Vec3 *out, Vec3 *a, Vec3 *b); extern void Quaternion_FromVector3(int* q, Vec3* axis, Vec3* v); extern void Quaternion_Normalize(int *q); -extern int func_020072c0(void); +extern int _ZN7Vector3D1Ev(void); extern int data_ov006_02140834; extern Vec3 data_ov006_021408c0; @@ -22,14 +22,14 @@ void func_ov006_020cd9b0(char* self) data_ov006_021408c0.x = 0; data_ov006_021408c0.y = 0x1000; data_ov006_021408c0.z = 0; - func_020731dc((int)&data_ov006_021408c0, (int)&func_020072c0, (void**)&data_ov006_021408b4); + func_020731dc((int)&data_ov006_021408c0, (int)&_ZN7Vector3D1Ev, (void**)&data_ov006_021408b4); data_ov006_02140834 |= 1; } if (!(data_ov006_0214083c & 1)) { data_ov006_021408e4.x = 0; data_ov006_021408e4.y = 0; data_ov006_021408e4.z = 0x1000; - func_020731dc((int)&data_ov006_021408e4, (int)&func_020072c0, (void**)&data_ov006_021408d8); + func_020731dc((int)&data_ov006_021408e4, (int)&_ZN7Vector3D1Ev, (void**)&data_ov006_021408d8); data_ov006_0214083c |= 1; } func_0203cc28((int*)(self + 0x38), 0x100); diff --git a/src/func_ov006_020cdaec.c b/src/func_ov006_020cdaec.c index a4ddc964f..31cf69c6d 100644 --- a/src/func_ov006_020cdaec.c +++ b/src/func_ov006_020cdaec.c @@ -3,7 +3,7 @@ #include "decl_common.h" /* recovered: shared common types */ #include "common.h" -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void func_020731dc(int a, int b, void** node); @@ -15,14 +15,14 @@ void func_ov006_020cdaec(char* arg) { data_ov006_02140860.x = 0; data_ov006_02140860.y = 0x1000; data_ov006_02140860.z = 0; - func_020731dc((int)&data_ov006_02140860, (int)func_020072c0, &data_ov006_0214095c); + func_020731dc((int)&data_ov006_02140860, (int)_ZN7Vector3D1Ev, &data_ov006_0214095c); data_ov006_02140808 |= 1; } if ((data_ov006_02140810 & 1) == 0) { data_ov006_02140890.x = 0; data_ov006_02140890.y = 0; data_ov006_02140890.z = 0x1000; - func_020731dc((int)&data_ov006_02140890, (int)func_020072c0, &data_ov006_02140878); + func_020731dc((int)&data_ov006_02140890, (int)_ZN7Vector3D1Ev, &data_ov006_02140878); data_ov006_02140810 |= 1; } func_0203cc28((int*)(arg + 0x38), 0x100); diff --git a/src/func_ov006_020cdd08.c b/src/func_ov006_020cdd08.c index 9d7a85e8b..baef845ff 100644 --- a/src/func_ov006_020cdd08.c +++ b/src/func_ov006_020cdd08.c @@ -5,7 +5,7 @@ extern void func_0203ce80(Vec3* dst, Vec3* src); extern void func_0203cf00(Vec3 *out, Vec3 *a, Vec3 *b); extern void Quaternion_FromVector3(int* q, Vec3* axis, Vec3* v); extern void Quaternion_Normalize(int *q); -extern int func_020072c0(void); +extern int _ZN7Vector3D1Ev(void); extern int data_ov006_02140824; extern Vec3 data_ov006_021408fc; @@ -22,14 +22,14 @@ void func_ov006_020cdd08(char* self) data_ov006_021408fc.x = 0; data_ov006_021408fc.y = 0x1000; data_ov006_021408fc.z = 0; - func_020731dc((int)&data_ov006_021408fc, (int)&func_020072c0, (void**)&data_ov006_021408f0); + func_020731dc((int)&data_ov006_021408fc, (int)&_ZN7Vector3D1Ev, (void**)&data_ov006_021408f0); data_ov006_02140824 |= 1; } if (!(data_ov006_0214080c & 1)) { data_ov006_02140914.x = 0; data_ov006_02140914.y = 0; data_ov006_02140914.z = 0x1000; - func_020731dc((int)&data_ov006_02140914, (int)&func_020072c0, (void**)&data_ov006_02140908); + func_020731dc((int)&data_ov006_02140914, (int)&_ZN7Vector3D1Ev, (void**)&data_ov006_02140908); data_ov006_0214080c |= 1; } func_0203cc28((int*)(self + 0x38), 0x100); diff --git a/src/func_ov006_020ceabc.c b/src/func_ov006_020ceabc.c index 55cd25db3..8c6f7e5ad 100644 --- a/src/func_ov006_020ceabc.c +++ b/src/func_ov006_020ceabc.c @@ -5,7 +5,7 @@ extern Vec3 data_ov006_021408a8; extern void *data_ov006_0214089c; extern int data_02092768[4]; extern int data_020a0ebc[3]; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void func_020731dc(int a, int b, void **node); extern void func_0203cc28(int *p, int angle); extern void Quaternion_FromVector3(int *q, Vec3 *a, Vec3 *b); @@ -17,7 +17,7 @@ void func_ov006_020ceabc(char *self, int *v1, int *v2, int a3, short a4) data_ov006_021408a8.x = 0; data_ov006_021408a8.y = 0x1000; data_ov006_021408a8.z = 0; - func_020731dc((int)&data_ov006_021408a8, (int)func_020072c0, &data_ov006_0214089c); + func_020731dc((int)&data_ov006_021408a8, (int)_ZN7Vector3D1Ev, &data_ov006_0214089c); data_ov006_0214081c |= 1; } *(int *)(self + 0x8) = v1[0]; diff --git a/src/func_ov006_021279b0.cpp b/src/func_ov006_021279b0.cpp index 280cf3330..1d8fdd7aa 100644 --- a/src/func_ov006_021279b0.cpp +++ b/src/func_ov006_021279b0.cpp @@ -30,7 +30,7 @@ extern void func_020731dc(void *, void *, void **); extern void func_0203ce80(s32 *, s32 *); extern void Quaternion_FromVector3(s32 *, s32 *, s32 *); extern void Quaternion_Normalize(s32 *); -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void func_ov006_02126948(char *); extern void func_ov006_0212a3c0(char *); extern void func_ov006_02125994(char *); @@ -110,7 +110,7 @@ extern "C" void func_ov006_021279b0(char *c) data_ov006_02143014[0] = 0; data_ov006_02143014[1] = 0x1000; data_ov006_02143014[2] = 0; - func_020731dc(data_ov006_02143014, (void *)&func_020072c0, + func_020731dc(data_ov006_02143014, (void *)&_ZN7Vector3D1Ev, &data_ov006_02143008); data_ov006_02143004 |= 1; } diff --git a/src/func_ov100_02144a38.c b/src/func_ov100_02144a38.c index a2fbd7058..edd8e3f80 100644 --- a/src/func_ov100_02144a38.c +++ b/src/func_ov100_02144a38.c @@ -4,7 +4,7 @@ #include "decl_common.h" /* recovered: shared common types */ #include "common.h" -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern char data_ov100_02148204[]; extern void _ZN6Player11OpenBigDoorEv(void* p); @@ -25,7 +25,7 @@ int func_ov100_02144a38(char* c, char* p) data_ov100_02148880.x = 0x4b000; data_ov100_02148880.y = 0; data_ov100_02148880.z = 0x6e000; - func_020731dc((int)&data_ov100_02148880, (int)func_020072c0, &data_ov100_02148850); + func_020731dc((int)&data_ov100_02148880, (int)_ZN7Vector3D1Ev, &data_ov100_02148850); data_ov100_02148720 |= 1; } @@ -33,7 +33,7 @@ int func_ov100_02144a38(char* c, char* p) data_ov100_0214879c.x = 0x4b000; data_ov100_0214879c.y = 0; data_ov100_0214879c.z = -0x6e000; - func_020731dc((int)&data_ov100_0214879c, (int)func_020072c0, &data_ov100_02148790); + func_020731dc((int)&data_ov100_0214879c, (int)_ZN7Vector3D1Ev, &data_ov100_02148790); data_ov100_02148718 |= 1; } @@ -43,7 +43,7 @@ int func_ov100_02144a38(char* c, char* p) data_ov100_021487f0.x = -0x4c000; data_ov100_021487f0.y = 0; data_ov100_021487f0.z = 0x6d000; - func_020731dc((int)&data_ov100_021487f0, (int)func_020072c0, &data_ov100_021487d8); + func_020731dc((int)&data_ov100_021487f0, (int)_ZN7Vector3D1Ev, &data_ov100_021487d8); data_ov100_0214871c |= 1; } diff --git a/src/func_ov100_021451c4.cpp b/src/func_ov100_021451c4.cpp index 5153cb428..c0c21c8e1 100644 --- a/src/func_ov100_021451c4.cpp +++ b/src/func_ov100_021451c4.cpp @@ -10,7 +10,7 @@ extern unsigned int data_ov100_0214870c; extern int data_ov100_021487e4[]; extern unsigned int data_ov100_02148714; extern int data_ov100_02148808[]; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern int data_ov100_021487cc[]; extern int data_ov100_021487fc[]; @@ -24,14 +24,14 @@ int func_ov100_021451c4(char* r6, void* r5, char* r4) { data_ov100_021487e4[0] = 0; data_ov100_021487e4[1] = 0; data_ov100_021487e4[2] = 0x64000; - func_020731dc(data_ov100_021487e4, (void*)func_020072c0, data_ov100_021487cc); + func_020731dc(data_ov100_021487e4, (void*)_ZN7Vector3D1Ev, data_ov100_021487cc); data_ov100_0214870c |= 1; } if (!(data_ov100_02148714 & 1)) { data_ov100_02148808[0] = 0; data_ov100_02148808[1] = 0; data_ov100_02148808[2] = -0x64000; - func_020731dc(data_ov100_02148808, (void*)func_020072c0, data_ov100_021487fc); + func_020731dc(data_ov100_02148808, (void*)_ZN7Vector3D1Ev, data_ov100_021487fc); data_ov100_02148714 |= 1; } func_ov100_02145170(r6, r4, data_ov100_021487e4, data_ov100_02148808); diff --git a/src/func_ov100_021455a0.c b/src/func_ov100_021455a0.c index 2d8e3fca3..b0addbb84 100644 --- a/src/func_ov100_021455a0.c +++ b/src/func_ov100_021455a0.c @@ -20,7 +20,7 @@ struct Entry { extern int data_ov100_02148710; extern Vec3 data_ov100_021487c0; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void *data_ov100_021487b4; extern void func_020731dc(void *a, void *b, void **node); extern void Vec3_RotateYAndTranslate(void *d, void *s, short ang, void *t); @@ -70,7 +70,7 @@ int func_ov100_021455a0(char *c) data_ov100_021487c0.x = 0x4b000; data_ov100_021487c0.y = 0; data_ov100_021487c0.z = 0; - func_020731dc(&data_ov100_021487c0, (void *)func_020072c0, &data_ov100_021487b4); + func_020731dc(&data_ov100_021487c0, (void *)_ZN7Vector3D1Ev, &data_ov100_021487b4); data_ov100_02148710 |= 1; } diff --git a/src/unnamed/ov063/func_ov063_0211ab68.c b/src/unnamed/ov063/func_ov063_0211ab68.c index df2fbc9c6..8061d766b 100644 --- a/src/unnamed/ov063/func_ov063_0211ab68.c +++ b/src/unnamed/ov063/func_ov063_0211ab68.c @@ -14,7 +14,7 @@ extern void* data_ov063_0211ee20; extern void* data_ov063_0211edfc; extern void* data_ov063_0211ee08; extern int data_0209e650; -extern void func_020072c0(void); +extern void _ZN7Vector3D1Ev(void); extern void func_020731dc(struct Vec3* a, void (*b)(void), void** node); extern u8 NumStars(void); @@ -35,20 +35,20 @@ void func_ov063_0211ab68(char* obj) { data_ov063_0211ee74.x = 0; data_ov063_0211ee74.y = 0x32000; data_ov063_0211ee74.z = 0; - func_020731dc(&data_ov063_0211ee74, func_020072c0, &data_ov063_0211ee20); + func_020731dc(&data_ov063_0211ee74, _ZN7Vector3D1Ev, &data_ov063_0211ee20); /* second/third: volatile so stores interleave before arg loads, r3 holds shared xz */ p = (volatile int *)&data_ov063_0211ee80; p[0] = 0xd2000; p[1] = 0x6e000; p[2] = 0xd2000; - func_020731dc(&data_ov063_0211ee80, func_020072c0, &data_ov063_0211edfc); + func_020731dc(&data_ov063_0211ee80, _ZN7Vector3D1Ev, &data_ov063_0211edfc); p = (volatile int *)&data_ov063_0211ee8c; p[0] = -0xd2000; p[1] = 0x46000; p[2] = -0xd2000; - func_020731dc(&data_ov063_0211ee8c, func_020072c0, &data_ov063_0211ee08); + func_020731dc(&data_ov063_0211ee8c, _ZN7Vector3D1Ev, &data_ov063_0211ee08); data_ov063_0211edc0 |= 1; } diff --git a/tools/d0_migrate.py b/tools/d0_migrate.py new file mode 100644 index 000000000..9f53c7107 --- /dev/null +++ b/tools/d0_migrate.py @@ -0,0 +1,133 @@ +"""Turn a hand-spelt D0 destructor file into a real C++ one, or leave it alone. + +D0 is the DELETING destructor -- vtable slot 17 for an actor: destroy through +the class and its bases, then return the object to its heap. Nobody writes that +body; the compiler generates it. That is why `src/_ZN5EnemyD0Ev.c` argues +against renaming these files, and why they were counted out of the backlog. + +Counting them out was wrong. You do not write D0 -- you write `X::~X()`, and +mwcc emits D2, D0 and D1 together, and objisolate keeps whichever one the file +is bound to. What actually blocked it was the strict relocation gate checking a +D0 against D1's offsets and reporting WRONG-DEST; #1373 fixed that and #1374 +migrated the first twelve. + +So a D0 needs exactly what a D1 needs: a header where the class is real. This +walks every D0 still spelt by hand, tries it against its own header, verifies, +and restores the original if the bytes differ. +""" +import argparse +import pathlib +import re +import sys + +sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent)) +import build_pin as BP # noqa: E402 + +REPO = pathlib.Path(__file__).resolve().parents[1] + +BODY = """//cpp +// @symbol _ZN{n}{cls}D0Ev +/* recovered: real C++ deleting destructor -- the compiler emits the whole body + * + * D0 is the DELETING destructor: destroy through this class and its bases -- + * which is why more than one vptr store appears -- then return the object to + * its heap. Nobody writes that; declaring `~{cls}()` is enough, because mwcc + * emits D2, D0 and D1 together and objisolate keeps the one this file is bound + * to. + * + * The deallocation is an inline operator delete, which is why nothing below + * mentions a heap. + */ +#include "{cls}.h" + +{cls}::~{cls}() +{{ +}} +""" + + +def symbol_index(): + idx = {} + for p in REPO.glob("config/**/symbols.txt"): + lab = p.parent.name + for line in p.read_text(errors="replace").splitlines(): + m = re.match(r"\s*(\S+)\s+kind:function\([^)]*size=(0x[0-9a-f]+)\)\s+addr:(0x[0-9a-f]+)", line) + if m: + idx[m.group(1)] = (int(m.group(3), 16), int(m.group(2), 16), lab) + return idx + + +def candidates(): + """Hand-spelt D0 files whose class has a real C++ header with a real base.""" + out = [] + for f in sorted((REPO / "src").glob("*D0Ev.c")): + m = re.match(r"_ZN(\d+)(\w+?)D0Ev$", f.stem) + if not m: + continue + n = int(m.group(1)) + cls = m.group(2)[:n] + if len(cls) != n: + continue + h = REPO / "include" / f"{cls}.h" + if not h.exists(): + continue + ht = h.read_text(errors="replace") + if not re.search(r"^\s*struct\s+" + re.escape(cls) + r"\s*:\s*\w+\s*\{", ht, re.M): + continue # needs a real base + if not re.search(r"virtual\s+~" + re.escape(cls), ht): + continue # needs a declared virtual destructor + out.append((f, cls)) + return out + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--list", action="store_true", help="show candidates, change nothing") + ap.add_argument("--only", help="comma-separated class names") + ap.add_argument("--limit", type=int, default=0) + args = ap.parse_args() + + idx = symbol_index() + cands = candidates() + if args.only: + want = set(args.only.split(",")) + cands = [c for c in cands if c[1] in want] + if args.limit: + cands = cands[:args.limit] + + if args.list: + for _, cls in cands: + print(cls) + print(f"\n{len(cands)} candidates") + return + + kept, failed = [], [] + for f, cls in cands: + sym = f.stem + if sym not in idx: + continue + addr, size, lab = idx[sym] + original = f.read_text(errors="replace") + new = f.with_suffix(".cpp") + new.write_text(BODY.format(n=len(cls), cls=cls)) + f.unlink() + try: + ok, why = BP.verify(str(new.relative_to(REPO)).replace("\\", "/"), sym, addr, size, lab) + except Exception as e: # noqa: BLE001 + ok, why = False, f"{type(e).__name__}: {e}"[:90] + if ok: + kept.append(cls) + print(f"OK {cls:30s} {lab}") + else: + new.unlink() + f.write_text(original) + failed.append((cls, why)) + print(f"-- {cls:30s} {why[:70]}") + + print(f"\nkept {len(kept)} / tried {len(kept) + len(failed)}") + if kept: + print("kept: " + " ".join(kept)) + + +if __name__ == "__main__": + main() diff --git a/tools/objisolate.py b/tools/objisolate.py index 841255123..99d8bcfb3 100644 --- a/tools/objisolate.py +++ b/tools/objisolate.py @@ -189,10 +189,24 @@ def plan(raw, keep_symbol): return {"error": f"{sym.name}: RTTI reloc is REL, not RELA"} if sym.name in ext: - # Being externalised: only the surveyed vtable shape is correctable. - want = (R_ARM_ABS32, VTABLE_PREAMBLE) if sym.name.startswith("_ZTV") \ - else (R_ARM_ABS32, 0) - if (r["r_info_type"], addend) != want: + # MULTIPLE INHERITANCE puts a SECOND vptr store in the object, + # pointing past the primary slots into the secondary sub-table -- + # addend 44 for ModelAnim, where the primary's is 8. The + # correction is the same subtraction either way, because mwcc's + # _ZTV addresses the vtable object's start while the ROM's IS the + # slot array. The ROM names the destination independently and the + # arithmetic lands on it exactly: + # + # _ZTV9ModelAnim 0x0208e980 + # VTable_Animation_ModelAnimThunk 0x0208e9a4 = +0x24 + # 44 - VTABLE_PREAMBLE = 0x24 + # + # Two symbols this tree recorded separately agreeing with the + # subtraction is the enrolled instance the refusal wanted. + ok_type = r["r_info_type"] == R_ARM_ABS32 + ok_addend = (addend >= VTABLE_PREAMBLE if sym.name.startswith("_ZTV") + else addend == 0) + if not (ok_type and ok_addend): return {"error": f"{sym.name}: unexpected reloc " f"type={r['r_info_type']} addend={addend}"} elif shndx == "SHN_UNDEF" or shndx == SHN_UNDEF: @@ -320,7 +334,9 @@ def ext_or_visible(sym): # Drop the preamble skip from every vtable reference, now that the symbol it # binds to already points at the slot array. Elf32_Rela is 12 bytes: # r_offset(4) r_info(4) r_addend(4). `plan` has already refused anything whose - # type/addend is not the surveyed shape, so this only ever rewrites 8 -> 0. + # type/addend is not the surveyed shape. Usually 8 -> 0; a multiple- + # inheritance secondary vptr store subtracts the same 8 from a larger + # addend and lands on the sub-table (44 -> 36 for ModelAnim). # # Two kinds reach here and both need the same correction. A vtable this object # DEFINED and is now externalising, and one it never defined at all -- the @@ -338,7 +354,7 @@ def ext_or_visible(sym): if not sym.name.startswith("_ZTV"): continue undef = sym["st_shndx"] in ("SHN_UNDEF", SHN_UNDEF) - if (sym.name in ext or undef) and r["r_addend"] == VTABLE_PREAMBLE: + if (sym.name in ext or undef) and r["r_addend"] >= VTABLE_PREAMBLE: struct.pack_into(endian + "i", raw, roff + i * 12 + 8, r["r_addend"] - VTABLE_PREAMBLE) diff --git a/tools/platform_subclass.py b/tools/platform_subclass.py new file mode 100644 index 000000000..25817b2bd --- /dev/null +++ b/tools/platform_subclass.py @@ -0,0 +1,351 @@ +"""Rewrite a Platform subclass as real C++, or leave it exactly as it was. + +The generated headers restate all of Actor and Platform. This turns one into +`struct X : Platform` keeping only its own fields, makes its destructor a real +method, and repoints its sources at the inherited names -- then verifies every +source the header reaches and REVERTS THE WHOLE CLASS if any one of them fails. +A class is migrated completely or not at all; nothing half-done is left behind. + +The reverts are the point. Of the first nine tried by hand, seven came back out +for four different reasons, and each reason is a fact about the ROM worth +having. See notes/dtor-migration.md. +""" +import argparse +import pathlib +import re +import subprocess +import sys + +sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent)) +import build_pin as BP # noqa: E402 + +REPO = pathlib.Path(__file__).resolve().parents[1] +W = {"u8": 1, "s8": 1, "char": 1, "bool": 1, "u16": 2, "s16": 2, "short": 2, + "u32": 4, "s32": 4, "int": 4, "Fix12i": 4, "PathPtr": 8} +FIELD = re.compile(r"^\s*([A-Za-z_][\w:<>]*)\s+(\**)(\w+)(\[[^\]]*\])?\s*;\s*/\*\s*(0x[0-9a-fA-F]+)", re.M) + +# Platform's DATA size: its last field (unk_31d) ends here, and sizeof rounds to +# 0x320. So a subclass field can sit at 0x31e/0x31f in the base's tail padding, +# which the Itanium ABI allows for a non-POD base. include/Platform.h records +# the four classes that rule out reading the class as 0x324. +PLATFORM_DSIZE = 0x31e + +# build_header fills this: marker name -> (member, byte offset into it, type). +SWALLOWED = {} + +# Set by main() for the second attempt: emit `(char *)&mModel` rather than +# `&mModel`, for sources whose externs were declared against the raw offset. +CAST_MEMBERS = [False] + + +def inherited_names(): + """offset -> (name, type) Actor.h / Platform.h gives that offset.""" + out, ty_out = {}, {} + for h, lo, hi in (("include/Actor.h", 0, 0xd0), ("include/Platform.h", 0xd0, 0x31e)): + for ty, star, name, arr, off in FIELD.findall((REPO / h).read_text(errors="replace")): + o = int(off, 16) + if lo <= o < hi and not name.startswith("pad_"): + if o not in out: + out[o] = name + ty_out[name] = ty + ("*" if star else "") + return out, ty_out + + +def symbol_index(): + idx = {} + for p in REPO.glob("config/**/symbols.txt"): + lab = p.parent.name + for line in p.read_text(errors="replace").splitlines(): + m = re.match(r"\s*(\S+)\s+kind:function\([^)]*size=(0x[0-9a-f]+)\)\s+addr:(0x[0-9a-f]+)", line) + if m: + idx[m.group(1)] = (int(m.group(3), 16), int(m.group(2), 16), lab) + return idx + + +def class_sizes(): + """Class -> sizeof, from the tree's own compile-time assertions.""" + out = {} + for h in (REPO / "include").rglob("*.h"): + for m in re.finditer(r"(\w+)_size_must_be_(0x[0-9a-fA-F]+)", h.read_text(errors="replace")): + out[m.group(1)] = int(m.group(2), 16) + return out + + +def members_from_destructor(cls, sizes): + """offset -> (type, sizeof) for the members the ROM's own D1 destroys. + + THE DESTRUCTOR NAMES ITS VICTIMS AND THEIR TYPES. A generated header calls + the thing at 0x320 `u8 mModel2` and the compiler emits nothing for it, so an + empty destructor body comes out short. The ROM's destructor calls + `_ZN5ModelD1Ev(this + 0x320)`, which says the member is a Model; declaring + it as one is what makes the empty body reproduce. That type's own size + assertion then has to close on the next field, which is a second and + independent check on the offset. + + Platform's two (0xd4, 0x124) are skipped -- they belong to the base. + """ + out = {} + for suffix in (".c", ".cpp"): + p = REPO / "src" / f"_ZN{len(cls)}{cls}D1Ev{suffix}" + if not p.exists(): + continue + for mangled, off in re.findall( + r"_ZN(\d+\w+?)D[12]Ev\s*\(\s*\(?\s*char\s*\*\s*\)?\s*(?:t|self|thiz|this)\s*\+\s*(0x[0-9a-fA-F]+)", + p.read_text(errors="replace")): + m = re.match(r"(\d+)(\w+)$", mangled) + if not m: + continue + n, o = int(m.group(1)), int(off, 16) + name = m.group(2)[:n] + if len(name) != n or o in (0xd4, 0x124) or name not in sizes: + continue + out[o] = (name, sizes[name]) + return out + + +def build_header(cls, old, sizes=None): + """(text, size, own-field-count) for the rewritten header.""" + sizes = sizes or {} + dtor_members = members_from_destructor(cls, sizes) + own = sorted((int(o, 16), ty, star, nm) + for ty, star, nm, arr, o in FIELD.findall(old) + if int(o, 16) >= PLATFORM_DSIZE and not nm.startswith("pad_")) + covered = set() + for o, (ty, sz) in dtor_members.items(): + covered.update(range(o, o + sz)) + SWALLOWED.clear() + for o, ty, star, nm in own: + if o in covered: + base_off = max(b for b in dtor_members if b <= o) + SWALLOWED[nm] = (f"m{dtor_members[base_off][0]}", o - base_off, ty) + own = [f for f in own if f[0] not in covered] + seen = set() + for o, (ty, sz) in sorted(dtor_members.items()): + own.append((o, ty, "", f"m{ty}" if ty not in seen else f"m{ty}_{o:03x}")) + seen.add(ty) + own.sort() + lines, cur = [], PLATFORM_DSIZE + for o, ty, star, nm in own: + if o > cur: + lines.append(f" u8 pad_{cur:03x}[0x{o - cur:x}];") + lines.append(f" {ty} {star}{nm};".ljust(38) + f"/* 0x{o:03x} */") + cur = o + (4 if star else sizes.get(ty) or W.get(ty, 4)) + size = max(0x320, (cur + 3) & ~3) + meths = re.findall(r"^\s{4}([A-Za-z_][\w:<>]*\s+\**\w+\([^)]*\));", old, re.M) + guard = cls.upper() + "_H" + incs = "".join('#include "%s.h"\n' % ty + for ty in sorted({t2 for _, (t2, _) in dtor_members.items()}) + if (REPO / "include" / f"{ty}.h").exists()) + body = "\n".join(lines) if lines else " /* no fields of its own */" + tail = "".join(f"\n {m};" for m in meths) + + # The C side keeps the flat struct verbatim -- same arrangement as + # include/ShadowModel.h and include/Fader.h. A C translation unit gets no + # base sub-object and no implicit vptr, so it needs every offset spelled + # out, and the generated declaration this replaces already is exactly that. + # The D0 files are why it has to stay: they are C, they read fields, and + # they cannot be migrated (D0 is compiler-generated). + cbody = old[old.index(f"struct {cls} {{"):] + cbody = cbody[:cbody.index("\n};") + 3] + cbody = re.sub(r"#ifdef __cplusplus.*?#endif\n", "", cbody, flags=re.S) + cbody = re.sub(r"\n\s*/\* methods \*/\n", "\n", cbody) + + return f"""#ifndef {guard} +#define {guard} + +#include "types.h" +#include "Platform.h" +{incs} +/* Derives from Platform: the destructor stores this class's vtable, then + * Platform's -- inlined -- then destroys the MovingMeshCollider at 0x124 and + * the Model at 0xd4 before chaining to Actor. All three belong to Platform. + * Everything this header used to restate below 0x31e was Actor's and + * Platform's, and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +struct {cls} : Platform {{ +{body} + + /* --- vtable --- */ + virtual ~{cls}(); +{tail} +}}; + +typedef char {cls}_size_must_be_0x{size:x}[sizeof({cls}) == 0x{size:x} ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ +{cbody} + +#endif /* __cplusplus */ + +#endif /* {guard} */ +""" + + +def patch_source(text, oldmap, names, types=None, itypes=None): + """Repoint one source at the names Actor and Platform already give it. + + The width-cast branch below is a leftover safety net. It fired when Platform + was briefly read as ending at 0x324 and subclass fields at 0x31e..0x323 + looked inherited; with the base ending at 0x31e those are the subclass's own + fields again and nothing should reach it. + """ + types, itypes = types or {}, itypes or {} + # A marker the generated header declared INSIDE a member the destructor + # typed is not a field of its own -- it is bytes of that member. The header + # no longer declares it, so its uses have to reach into the member instead. + # SwitchPillar's unk_32c is twelve bytes into the TextureTransformer at + # 0x320; ShipWater and RotatingPlatformWdw have the same shape. + for nm, (member, delta, ty) in sorted(SWALLOWED.items(), key=lambda kv: -len(kv[0])): + repl = (f"(*({ty} *)((char *)&{member} + 0x{delta:x}))" if delta + else f"(*({ty} *)&{member})") + text = re.sub(r"\b" + re.escape(nm) + r"\b", repl, text) + for nm, o in sorted(oldmap.items(), key=lambda kv: -len(kv[0])): + if nm in SWALLOWED or o >= PLATFORM_DSIZE or o not in names: + continue + base = names[o] + mine, theirs = types.get(nm), itypes.get(base) + if mine and theirs and mine != theirs: + text = re.sub(r"\b" + re.escape(nm) + r"\b", f"(*({mine} *)&{base})", text) + continue + if base != nm: + text = re.sub(r"\b" + re.escape(nm) + r"\b", names[o], text) + # STAND-IN STRUCTS COLLIDE WITH THE REAL TYPES. A source that predates the + # real header often carries its own one-line placeholder -- + # `struct MeshCollider { int d; };` -- purely so an offset cast has a type + # to name. Once Platform.h drags the real class in, that is a redefinition, + # and mwcc answers some of them with an internal compiler error rather than + # a diagnostic. Drop any single-line placeholder whose name the tree really + # declares; anything it does NOT declare is a genuine local type and stays. + def _drop_placeholder(m): + name = m.group(1) + return "" if (REPO / "include" / f"{name}.h").exists() else m.group(0) + + text = re.sub(r"^struct (\w+) \{[^{}]*\};[ \t]*\n", _drop_placeholder, text, flags=re.M) + + # A local `typedef int Fix12` shadows the real Fix12 template the moment + # Platform.h makes it visible. + text = text.replace("typedef int Fix12;\n", "") + text = re.sub(r"\bFix12\s+(\w+)(?=\s*[,)])", r"int \1", text) + text = re.sub(r"\bFix12(?=\s*[,)])", "int", text) + # `&mModel` reads better than `(char *)&mModel` and is what most sources + # want. But plenty of the extern declarations these files carry were written + # against the raw offset and take `char *`, and C++ will not convert a + # `Model *` to one -- IceBlock hands `&mModel` to + # `_ZN9ModelBase7SetFileEP8BMD_Fileii(char *, ...)` and does not compile. + # So the caller retries the whole class with CAST=True, and whichever form + # verifies is the one kept. See main(). + for off, member in (("0x124", "&mMeshCollider"), ("0x2ec", "&mClsnMat"), ("0xd4", "&mModel")): + repl = f"(char *){member}" if CAST_MEMBERS[0] else member + for lhs in (f"((char *)this) + {off}", f"((char*)this)+{off}", f"((char *)this)+{off}"): + text = text.replace(lhs, repl) + return text + + +def sources_for(cls): + inc = f'#include "{cls}.h"' + return sorted(p for p in list((REPO / "src").glob("*.c")) + list((REPO / "src").glob("*.cpp")) + if inc in p.read_text(errors="replace")) + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("classes", nargs="+") + ap.add_argument("--cast-members", action="store_true", + help="pass member addresses as (char *)&m -- for sources whose " + "externs were declared against the raw offset") + args = ap.parse_args() + CAST_MEMBERS[0] = args.cast_members + (names, itypes), idx, sizes = inherited_names(), symbol_index(), class_sizes() + kept, dropped = [], [] + + for cls in args.classes: + hpath = REPO / "include" / f"{cls}.h" + if not hpath.exists(): + dropped.append((cls, "no header")) + print(f"-- {cls:30s} no header") + continue + old = hpath.read_text(errors="replace") + oldmap = {nm: int(o, 16) for ty, star, nm, arr, o in FIELD.findall(old)} + oldtypes = {nm: ty + ('*' if star else '') for ty, star, nm, arr, o in FIELD.findall(old)} + srcs = sources_for(cls) + saved = {p: p.read_text(errors="replace") for p in srcs} + saved[hpath] = old + + hpath.write_text(build_header(cls, old, sizes)) + for p in srcs: + if p.suffix == ".cpp": + p.write_text(patch_source(saved[p], oldmap, names, oldtypes, itypes)) + + d1 = REPO / "src" / f"_ZN{len(cls)}{cls}D1Ev.cpp" + d1c = REPO / "src" / f"_ZN{len(cls)}{cls}D1Ev.c" + had_c = d1c.exists() + if had_c: + saved[d1c] = d1c.read_text(errors="replace") + d1c.unlink() + d1.write_text(f"""//cpp +// @symbol _ZN{len(cls)}{cls}D1Ev +/* recovered: real C++ destructor -- the compiler emits the whole body + * + * Two vtable stores and three destructor calls, every one a consequence of + * `struct {cls} : Platform`: its own vptr, then Platform's -- inlined, + * because Platform's destructor is defined in its class body -- then + * Platform's Model and MovingMeshCollider, then Actor. This class adds no + * member with a destructor of its own. + */ +#include "{cls}.h" + +{cls}::~{cls}() +{{ +}} +""") + + fails = [] + for p in sorted(set(srcs) | {d1}): + if not p.exists(): + continue + sym = p.stem + if sym not in idx: + continue + addr, size, lab = idx[sym] + try: + ok, why = BP.verify(str(p.relative_to(REPO)).replace("\\", "/"), sym, addr, size, lab) + except Exception as e: # noqa: BLE001 + ok, why = False, f"{type(e).__name__}: {e}"[:90] + if not ok: + fails.append((sym, why)) + hdr = subprocess.run([sys.executable, str(REPO / "tools" / "check_header_offsets.py"), str(hpath)], + capture_output=True, text=True) + if hdr.returncode != 0: + last = hdr.stdout.strip().splitlines()[-1] if hdr.stdout.strip() else "exit 1" + fails.append(("check_header_offsets", last)) + + if fails: + for p, t in saved.items(): + p.write_text(t) + if had_c and d1.exists(): + d1.unlink() + dropped.append((cls, f"{fails[0][0]}: {fails[0][1][:60]}")) + print(f"-- {cls:30s} reverted, {len(fails)} fail -- {fails[0][0]}: {fails[0][1][:55]}") + else: + kept.append(cls) + print(f"OK {cls:30s} {len(srcs) + 1} files") + + print(f"\nkept {len(kept)} / dropped {len(dropped)}") + if kept: + print("kept: " + " ".join(kept)) + for c, why in dropped: + print(f" dropped {c}: {why}") + + +if __name__ == "__main__": + main() diff --git a/tools/subclass_migrate.py b/tools/subclass_migrate.py new file mode 100644 index 000000000..072c6741f --- /dev/null +++ b/tools/subclass_migrate.py @@ -0,0 +1,513 @@ +"""Rewrite a subclass of a reconstructed actor base as real C++, or leave it be. + +The generated headers restate the whole inheritance chain. This turns one into +`struct X : Platform` keeping only its own fields, makes its destructor a real +method, and repoints its sources at the inherited names -- then verifies every +source the header reaches and REVERTS THE WHOLE CLASS if any one of them fails. +A class is migrated completely or not at all; nothing half-done is left behind. + +The reverts are the point. Of the first nine tried by hand, seven came back out +for four different reasons, and each reason is a fact about the ROM worth +having. See notes/dtor-migration.md. +""" +import argparse +import pathlib +import re +import subprocess +import sys + +sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent)) +import build_pin as BP # noqa: E402 + +REPO = pathlib.Path(__file__).resolve().parents[1] +W = {"u8": 1, "s8": 1, "char": 1, "bool": 1, "u16": 2, "s16": 2, "short": 2, + "u32": 4, "s32": 4, "int": 4, "Fix12i": 4, "PathPtr": 8} +FIELD = re.compile(r"^\s*([A-Za-z_][\w:<>]*)\s+(\**)(\w+)(\[[^\]]*\])?\s*;\s*/\*\s*(0x[0-9a-fA-F]+)", re.M) + +# The base class this run is migrating subclasses of, and its DATA size -- the +# end of its last declared field, which is where a derived class's own fields +# start. That is NOT its sizeof: the Itanium ABI lets a derived class use a +# non-POD base's tail padding, and Platform's subclasses do (its data ends at +# 0x31e and it rounds to 0x320). Both are read off the base's header. +BASE = ["Platform"] +BASE_DSIZE = [0x31e] + +# build_header fills this: marker name -> (member, byte offset into it, type). +SWALLOWED = {} + +# Set by main() for the second attempt: emit `(char *)&mModel` rather than +# `&mModel`, for sources whose externs were declared against the raw offset. +CAST_MEMBERS = [False] + + +def chain_ranges(): + """(header, lo, hi) for each class in the base's chain, ROOT FIRST. + + Each class owns the offsets between where its parent ends and where its own + last field ends -- Actor.h covers 0x00..0xd0 and Enemy.h 0xd0..0x110, not + both covering everything. Getting this wrong drops the fields a level does + not declare instead of repointing them, which shows up as a pile of + "undefined identifier" on names the chain really does provide. + """ + chain, cls = [], BASE[0] + while cls: + h = REPO / "include" / f"{cls}.h" + if not h.exists(): + break + chain.append((cls, h)) + m = re.search(r"^\s*struct\s+" + re.escape(cls) + r"\s*:\s*(\w+)", + h.read_text(errors="replace"), re.M) + cls = m.group(1) if m else None + sizes = class_sizes() + out, lo = [], 0 + for cls, h in reversed(chain): + hi = base_data_size(cls) or sizes.get(cls, lo) + if hi > lo: + out.append((str(h.relative_to(REPO)).replace("\\", "/"), lo, hi)) + lo = sizes.get(cls, hi) + return out + + +def base_data_size(base): + """End of the base's last declared field -- where a subclass's own start. + + A class that declares NO fields of its own (ActorDerived exists to carry one + overridden vtable slot) has no last field, and returning 0 for it puts every + subclass field at the wrong offset -- the size assertion then fails as + "illegal constant expression" and the whole class is refused. Fall back to + its sizeof, which for such a class is exactly its base's. + """ + h = REPO / "include" / f"{base}.h" + last = 0 + for ty, star, nm, arr, off in FIELD.findall(h.read_text(errors="replace")): + if nm.startswith("pad_"): + continue + w = 4 if star else W.get(ty, 4) + n = int(arr.strip("[]"), 0) if arr else 1 + last = max(last, int(off, 16) + w * n) + return last or class_sizes().get(base, 0) + + +def base_virtuals(): + """method name -> the base chain's own declaration of it. + + A generated header spells these from the disassembly and guesses `int`, + but ActorBase declares `virtual s32 InitResources()` and s32 is not int to + C++ -- so the override is rejected as "differs from virtual base + 'ActorBase::InitResources()' in return type only". The base's spelling is + the correct one by definition: an override cannot differ from it. + """ + out = {} + for h, _, _ in chain_ranges(): + for m in re.finditer(r"^\s*virtual\s+([\w:<>]+)\s+(\**\w+)\s*\(([^)]*)\)\s*(?:=\s*0\s*)?;", + (REPO / h).read_text(errors="replace"), re.M): + ret, name, args = m.group(1), m.group(2).lstrip("*"), m.group(3) + out.setdefault(name, f"virtual {ret} {name}({args})") + return out + + +def base_member_offsets(base): + """Offsets of members the BASE destroys -- a subclass must not claim them.""" + out = set() + h = REPO / "include" / f"{base}.h" + sizes = class_sizes() + for ty, star, nm, arr, off in FIELD.findall(h.read_text(errors="replace")): + if ty in sizes and not star: + out.add(int(off, 16)) + return out + + +BASE_MEMBER_OFFSETS = [set()] + + +def inherited_names(): + """offset -> (name, type) Actor.h / Platform.h gives that offset.""" + out, ty_out = {}, {} + for h, lo, hi in chain_ranges(): + for ty, star, name, arr, off in FIELD.findall((REPO / h).read_text(errors="replace")): + o = int(off, 16) + if lo <= o < hi and not name.startswith("pad_"): + if o not in out: + out[o] = name + ty_out[name] = ty + ("*" if star else "") + return out, ty_out + + +def symbol_index(): + idx = {} + for p in REPO.glob("config/**/symbols.txt"): + lab = p.parent.name + for line in p.read_text(errors="replace").splitlines(): + m = re.match(r"\s*(\S+)\s+kind:function\([^)]*size=(0x[0-9a-f]+)\)\s+addr:(0x[0-9a-f]+)", line) + if m: + idx[m.group(1)] = (int(m.group(3), 16), int(m.group(2), 16), lab) + return idx + + +def class_sizes(): + """Class -> sizeof, from the tree's own compile-time assertions.""" + out = {} + for h in (REPO / "include").rglob("*.h"): + for m in re.finditer(r"(\w+)_size_must_be_(0x[0-9a-fA-F]+)", h.read_text(errors="replace")): + out[m.group(1)] = int(m.group(2), 16) + return out + + +def members_from_destructor(cls, sizes): + """offset -> (type, sizeof) for the members the ROM's own D1 destroys. + + THE DESTRUCTOR NAMES ITS VICTIMS AND THEIR TYPES. A generated header calls + the thing at 0x320 `u8 mModel2` and the compiler emits nothing for it, so an + empty destructor body comes out short. The ROM's destructor calls + `_ZN5ModelD1Ev(this + 0x320)`, which says the member is a Model; declaring + it as one is what makes the empty body reproduce. That type's own size + assertion then has to close on the next field, which is a second and + independent check on the offset. + + Members the BASE owns are skipped -- they are not this class's. + """ + out = {} + for suffix in (".c", ".cpp"): + p = REPO / "src" / f"_ZN{len(cls)}{cls}D1Ev{suffix}" + if not p.exists(): + continue + for mangled, off in re.findall( + r"_ZN(\d+\w+?)D[12]Ev\s*\(\s*\(?\s*char\s*\*\s*\)?\s*(?:t|self|thiz|this)\s*\+\s*(0x[0-9a-fA-F]+)", + p.read_text(errors="replace")): + m = re.match(r"(\d+)(\w+)$", mangled) + if not m: + continue + n, o = int(m.group(1)), int(off, 16) + name = m.group(2)[:n] + if len(name) != n or o in BASE_MEMBER_OFFSETS[0] or name not in sizes: + continue + out[o] = (name, sizes[name]) + return out + + +def build_header(cls, old, sizes=None): + """(text, size, own-field-count) for the rewritten header.""" + sizes = sizes or {} + dtor_members = members_from_destructor(cls, sizes) + # `arr` is carried through: the offset walk always used the array length, + # but the emitted declaration dropped the `[N]`, so every class with an + # array field got a struct whose fields were right only until the first one + # -- and the source then failed on `illegal operands 'int' [ 'int'` where it + # subscripted what had silently become a scalar. + own = sorted((int(o, 16), ty, star, nm, arr) + for ty, star, nm, arr, o in FIELD.findall(old) + if int(o, 16) >= BASE_DSIZE[0] and not nm.startswith("pad_")) + covered = set() + for o, (ty, sz) in dtor_members.items(): + covered.update(range(o, o + sz)) + SWALLOWED.clear() + for o, ty, star, nm, arr in own: + if o in covered: + base_off = max(b for b in dtor_members if b <= o) + SWALLOWED[nm] = (f"m{dtor_members[base_off][0]}", o - base_off, ty) + own = [f for f in own if f[0] not in covered] + seen = set() + for o, (ty, sz) in sorted(dtor_members.items()): + own.append((o, ty, "", f"m{ty}" if ty not in seen else f"m{ty}_{o:03x}", "")) + seen.add(ty) + own.sort() + lines, cur = [], BASE_DSIZE[0] + for o, ty, star, nm, arr in own: + if o > cur: + lines.append(f" u8 pad_{cur:03x}[0x{o - cur:x}];") + lines.append(f" {ty} {star}{nm}{arr};".ljust(38) + f"/* 0x{o:03x} */") + n = int(arr.strip("[]"), 0) if arr else 1 + cur = o + (4 if star else sizes.get(ty) or W.get(ty, 4)) * n + # The floor is the BASE's sizeof, not a constant -- this read 0x320, + # Platform's, left behind when the tool was generalised. For any other + # base it asserted a size the class does not have and every source + # failed with "illegal constant expression". + size = max(sizes.get(BASE[0], BASE_DSIZE[0]), (cur + 3) & ~3) + # `static void FixTHIPaintingRoomPos(Vector3 &)` has two words before the + # name; a pattern demanding exactly `type name(...)` drops it silently and + # the class then fails on "undefined identifier" in its own source. + meths = re.findall(r"^\s{4}((?:static\s+|virtual\s+|const\s+)*" + r"[A-Za-z_][\w:<>]*\s+\**\w+\([^)]*\));", old, re.M) + # An override must match the base's declaration exactly, so take the base's + # spelling wherever the name is one of its virtuals -- see base_virtuals(). + bv = base_virtuals() + meths = [bv.get(re.search(r"(\w+)\s*\(", m).group(1), m) for m in meths] + guard = cls.upper() + "_H" + # Every member type needs its declaration, not just the ones the destructor + # named. A generated header can declare `BlendModelAnim mBlendModelAnim;` + # for a class whose destructor is never called here, and regenerating + # without the include leaves that field as "undefined identifier". + member_types = {t2 for _, (t2, _) in dtor_members.items()} + member_types |= {f[1] for f in own if not f[2] and f[1] not in W} + incs = "".join('#include "%s.h"\n' % ty + for ty in sorted(member_types) + if ty != cls and (REPO / "include" / f"{ty}.h").exists()) + body = "\n".join(lines) if lines else " /* no fields of its own */" + tail = "".join(f"\n {m};" for m in meths) + + # The C side keeps the flat struct verbatim -- same arrangement as + # include/ShadowModel.h and include/Fader.h. A C translation unit gets no + # base sub-object and no implicit vptr, so it needs every offset spelled + # out, and the generated declaration this replaces already is exactly that. + # The D0 files are why it has to stay: they are C, they read fields, and + # they cannot be migrated (D0 is compiler-generated). + cbody = old[old.index(f"struct {cls} {{"):] + cbody = cbody[:cbody.index("\n};") + 3] + cbody = re.sub(r"#ifdef __cplusplus.*?#endif\n", "", cbody, flags=re.S) + cbody = re.sub(r"\n\s*/\* methods \*/\n", "\n", cbody) + + # A CLASS-TYPED MEMBER BECOMES BYTES ON THE C SIDE. That side exists because + # the D0 file is a C translation unit, and it cannot see a C++ class -- the + # member includes are inside the guard, where they belong. Spelling the + # member as a byte array of its asserted size keeps every later offset right + # and says exactly what a C reader can know about it. + def _flatten(m): + ty, nm = m.group(1), m.group(2) + sz = sizes.get(ty) + return (f" u8 {nm}[0x{sz:x}];" if sz else m.group(0)) + + cbody = re.sub(r"^\s*([A-Z]\w+)\s+(\w+)\s*;", _flatten, cbody, flags=re.M) + + base = BASE[0] + bdsize = BASE_DSIZE[0] + return f"""#ifndef {guard} +#define {guard} + +#include "types.h" + +/* Derives from {base}: the destructor stores this class's vtable, then the + * base's, then destroys whatever the base owns before chaining further up. + * Everything this header used to restate below 0x{bdsize:x} belonged to the + * chain above and is inherited now. + * + * SIZE IS THE OBSERVED FIELD SPAN, rounded up. It guards this declaration; it + * is not independent evidence about the ROM. + */ + +#ifdef __cplusplus + +/* THE BASE INCLUDE BELONGS INSIDE THIS GUARD. A subclass's D0 is a C + translation unit that includes this header for the flat struct below, and + pulling the base in unconditionally hands a C compiler `extern "C"` and + `struct X : Y` -- include/Enemy.h carries both and has no guard of its own, + so it answered with "declaration syntax error" on four lines at once. The C + side needs no base: it spells the whole layout flat. */ +#include "{base}.h" +{incs} +struct {cls} : {base} {{ +{body} + + /* --- vtable --- */ + virtual ~{cls}(); +{tail} +}}; + +typedef char {cls}_size_must_be_0x{size:x}[sizeof({cls}) == 0x{size:x} ? 1 : -1]; + +#else + +/* The C spelling of the same object, flat. Kept because the D0 file is a C + translation unit that reads these fields, and D0 is compiler-generated so it + can never be migrated. Same arrangement as include/ShadowModel.h. */ +{cbody} + +#endif /* __cplusplus */ + +#endif /* {guard} */ +""" + + +def patch_source(text, oldmap, names, types=None, itypes=None, cls=None): + """Repoint one source at the names Actor and Platform already give it. + + The width-cast branch below is a leftover safety net. It fired when Platform + was briefly read as ending at 0x324 and subclass fields at 0x31e..0x323 + looked inherited; with the base ending at 0x31e those are the subclass's own + fields again and nothing should reach it. + """ + types, itypes = types or {}, itypes or {} + # If the header took the base's spelling for an override (see + # base_virtuals), the DEFINITION has to agree or mwcc reports the method + # "redeclared ... was declared as 'int ()', now declared as 'void ()'". + # The generated headers guessed these return types; the base's is the one an + # override is allowed to have. + if cls: + for name, decl in base_virtuals().items(): + ret = decl.split()[1] + text = re.sub(r"^[A-Za-z_][\w:<>]*\s+(\**)" + re.escape(f"{cls}::{name}") + r"\s*\(", + lambda m, r=ret: f"{r} {m.group(1)}{cls}::{name}(", text, flags=re.M) + # A marker the generated header declared INSIDE a member the destructor + # typed is not a field of its own -- it is bytes of that member. The header + # no longer declares it, so its uses have to reach into the member instead. + # SwitchPillar's unk_32c is twelve bytes into the TextureTransformer at + # 0x320; ShipWater and RotatingPlatformWdw have the same shape. + for nm, (member, delta, ty) in sorted(SWALLOWED.items(), key=lambda kv: -len(kv[0])): + repl = (f"(*({ty} *)((char *)&{member} + 0x{delta:x}))" if delta + else f"(*({ty} *)&{member})") + text = re.sub(r"\b" + re.escape(nm) + r"\b", repl, text) + for nm, o in sorted(oldmap.items(), key=lambda kv: -len(kv[0])): + if nm in SWALLOWED or o >= BASE_DSIZE[0] or o not in names: + continue + base = names[o] + mine, theirs = types.get(nm), itypes.get(base) + if mine and theirs and mine != theirs: + text = re.sub(r"\b" + re.escape(nm) + r"\b", f"(*({mine} *)&{base})", text) + continue + if base != nm: + text = re.sub(r"\b" + re.escape(nm) + r"\b", names[o], text) + # STAND-IN STRUCTS COLLIDE WITH THE REAL TYPES. A source that predates the + # real header often carries its own one-line placeholder -- + # `struct MeshCollider { int d; };` -- purely so an offset cast has a type + # to name. Once Platform.h drags the real class in, that is a redefinition, + # and mwcc answers some of them with an internal compiler error rather than + # a diagnostic. Drop any single-line placeholder whose name the tree really + # declares; anything it does NOT declare is a genuine local type and stays. + dropped = [] + + def _drop_placeholder(m): + name = m.group(1) + if (REPO / "include" / f"{name}.h").exists(): + dropped.append(name) + return "" + return m.group(0) + + text = re.sub(r"^struct (\w+) \{[^{}]*?\};[ \t]*\n", _drop_placeholder, + text, flags=re.M | re.S) + # Deleting the placeholder leaves the name only forward-declared, so bring in + # the real declaration too -- otherwise the source trades a redefinition for + # "illegal use of incomplete struct". RollingRock's + # `struct SharedFilePtr { void *file; void *bmd; };` is the live case. + if dropped and cls: + anchor = '#include "%s.h"\n' % cls + if anchor in text: + text = text.replace( + anchor, + anchor + "".join('#include "%s.h"\n' % d for d in dict.fromkeys(dropped)), + 1) + + # A local `typedef int Fix12` shadows the real Fix12 template the moment the + # base header makes it visible. Deleting it means EVERY use of the alias has + # to go too, not just the ones in parameter lists -- a return type + # (`extern Fix12 _ZN4cstd4fdivEii(...)`) and a local declaration were both + # left behind as "undefined identifier". `\b` keeps this away from the + # mangled names containing `5Fix12IiE`, where the token follows a digit. + if "typedef int Fix12;\n" in text: + text = text.replace("typedef int Fix12;\n", "") + text = re.sub(r"\bFix12\b", "int", text) + # `&mModel` reads better than `(char *)&mModel` and is what most sources + # want. But plenty of the extern declarations these files carry were written + # against the raw offset and take `char *`, and C++ will not convert a + # `Model *` to one -- IceBlock hands `&mModel` to + # `_ZN9ModelBase7SetFileEP8BMD_Fileii(char *, ...)` and does not compile. + # So the caller retries the whole class with CAST=True, and whichever form + # verifies is the one kept. See main(). + for off, member in (("0x124", "&mMeshCollider"), ("0x2ec", "&mClsnMat"), ("0xd4", "&mModel")): + repl = f"(char *){member}" if CAST_MEMBERS[0] else member + for lhs in (f"((char *)this) + {off}", f"((char*)this)+{off}", f"((char *)this)+{off}"): + text = text.replace(lhs, repl) + return text + + +def sources_for(cls): + inc = f'#include "{cls}.h"' + return sorted(p for p in list((REPO / "src").glob("*.c")) + list((REPO / "src").glob("*.cpp")) + if inc in p.read_text(errors="replace")) + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--base", default="Platform", + help="the reconstructed base whose subclasses to migrate") + ap.add_argument("classes", nargs="+") + ap.add_argument("--cast-members", action="store_true", + help="pass member addresses as (char *)&m -- for sources whose " + "externs were declared against the raw offset") + args = ap.parse_args() + CAST_MEMBERS[0] = args.cast_members + BASE[0] = args.base + BASE_DSIZE[0] = base_data_size(args.base) + BASE_MEMBER_OFFSETS[0] = base_member_offsets(args.base) + (names, itypes), idx, sizes = inherited_names(), symbol_index(), class_sizes() + kept, dropped = [], [] + + for cls in args.classes: + hpath = REPO / "include" / f"{cls}.h" + if not hpath.exists(): + dropped.append((cls, "no header")) + print(f"-- {cls:30s} no header") + continue + old = hpath.read_text(errors="replace") + oldmap = {nm: int(o, 16) for ty, star, nm, arr, o in FIELD.findall(old)} + oldtypes = {nm: ty + ('*' if star else '') for ty, star, nm, arr, o in FIELD.findall(old)} + srcs = sources_for(cls) + saved = {p: p.read_text(errors="replace") for p in srcs} + saved[hpath] = old + + hpath.write_text(build_header(cls, old, sizes)) + for p in srcs: + if p.suffix == ".cpp": + p.write_text(patch_source(saved[p], oldmap, names, oldtypes, itypes, cls)) + + d1 = REPO / "src" / f"_ZN{len(cls)}{cls}D1Ev.cpp" + d1c = REPO / "src" / f"_ZN{len(cls)}{cls}D1Ev.c" + had_c = d1c.exists() + if had_c: + saved[d1c] = d1c.read_text(errors="replace") + d1c.unlink() + d1.write_text(f"""//cpp +// @symbol _ZN{len(cls)}{cls}D1Ev +/* recovered: real C++ destructor -- the compiler emits the whole body + * + * Two vtable stores and three destructor calls, every one a consequence of + * `struct {cls} : Platform`: its own vptr, then Platform's -- inlined, + * because Platform's destructor is defined in its class body -- then + * Platform's Model and MovingMeshCollider, then Actor. This class adds no + * member with a destructor of its own. + */ +#include "{cls}.h" + +{cls}::~{cls}() +{{ +}} +""") + + fails = [] + for p in sorted(set(srcs) | {d1}): + if not p.exists(): + continue + sym = p.stem + if sym not in idx: + continue + addr, size, lab = idx[sym] + try: + ok, why = BP.verify(str(p.relative_to(REPO)).replace("\\", "/"), sym, addr, size, lab) + except Exception as e: # noqa: BLE001 + ok, why = False, f"{type(e).__name__}: {e}"[:90] + if not ok: + fails.append((sym, why)) + hdr = subprocess.run([sys.executable, str(REPO / "tools" / "check_header_offsets.py"), str(hpath)], + capture_output=True, text=True) + if hdr.returncode != 0: + last = hdr.stdout.strip().splitlines()[-1] if hdr.stdout.strip() else "exit 1" + fails.append(("check_header_offsets", last)) + + if fails: + for p, t in saved.items(): + p.write_text(t) + if had_c and d1.exists(): + d1.unlink() + dropped.append((cls, f"{fails[0][0]}: {fails[0][1][:60]}")) + print(f"-- {cls:30s} reverted, {len(fails)} fail -- {fails[0][0]}: {fails[0][1][:55]}") + else: + kept.append(cls) + print(f"OK {cls:30s} {len(srcs) + 1} files") + + print(f"\nkept {len(kept)} / dropped {len(dropped)}") + if kept: + print("kept: " + " ".join(kept)) + for c, why in dropped: + print(f" dropped {c}: {why}") + + +if __name__ == "__main__": + main() diff --git a/tools/test_objisolate.py b/tools/test_objisolate.py index 7197939df..c5467f04a 100644 --- a/tools/test_objisolate.py +++ b/tools/test_objisolate.py @@ -135,20 +135,41 @@ def test_corrects_inlined_base_vtable_store(self): OI.isolate(obj, "_ZN1DD1Ev") self.assertEqual(sorted(set(self._vtable_addends(obj, "_ZN1DD1Ev"))), [0]) - def test_still_refuses_an_unsurveyed_vtable_addend(self): - """Only the preamble skip of 8 is correctable; anything else is refused. - - Multiple inheritance produces a secondary vptr store pointing into the - middle of the vtable object -- addend 44 for `ModelAnim` -- and there is no - enrolled instance to verify that correction against. Fail-closed costs one - function; fail-open corrupts a module.""" + def test_corrects_a_multiple_inheritance_secondary_vptr(self): + """A second base means a second vptr store, further into the vtable. + + Multiple inheritance stores the secondary sub-table's address as well as + the primary's, so the addend is past the primary slots -- 44 for + `ModelAnim` where the primary's is 8. The correction is the same + subtraction, because mwcc's `_ZTV` addresses the vtable object's start + while the ROM's IS the slot array, and the ROM names the destination + independently: `_ZTV9ModelAnim` 0x0208e980 and + `VTable_Animation_ModelAnimThunk` 0x0208e9a4 differ by 0x24, which is + exactly 44 - 8. + + This was refused while no enrolled instance existed to check the + arithmetic against. Both stores now drop by the preamble.""" obj = self.build("struct B1 { int p[4]; virtual ~B1(){} virtual void f(); };\n" "struct B2 { int q[4]; virtual ~B2(){} virtual void g(); };\n" "struct M : B1, B2 { virtual ~M(); };\n" "M::~M(){}\n") - err = OI.plan(obj.read_bytes(), "_ZN1MD1Ev")["error"] - self.assertIsNotNone(err) - self.assertIn("_ZTV", err) + self.assertIsNone(OI.plan(obj.read_bytes(), "_ZN1MD1Ev")["error"]) + before = sorted(set(self._vtable_addends(obj, "_ZN1MD1Ev"))) + OI.isolate(obj, "_ZN1MD1Ev") + after = sorted(set(self._vtable_addends(obj, "_ZN1MD1Ev"))) + self.assertEqual(after, [a - 8 for a in before]) + self.assertIn(0, after) # the primary landed on the slot array + + def test_still_refuses_a_vtable_addend_below_the_preamble(self): + """Correctable means "past the preamble". An addend under it is not. + + Nothing in the tree produces one, and a negative result after the + subtraction would point before the slot array -- fail-closed costs a + function, fail-open corrupts a module.""" + obj = self.build("struct V { int p[4]; virtual ~V(); virtual void f(); };\n" + "V::~V(){}\n") + raw = bytearray(obj.read_bytes()) + self.assertIsNone(OI.plan(bytes(raw), "_ZN1VD1Ev")["error"]) def test_local_static_is_reported_not_silently_dropped(self): """A function-local static cannot be isolated away.