From 4698a889ebd3134ba9feaaaf37328d26c65241f1 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sat, 11 Apr 2026 20:37:32 +0200 Subject: [PATCH 1/7] Fix daBaseNpc_c field_0x744 array size (#3154) --- include/d/actor/d_a_npc2.h | 3 +-- src/d/actor/d_a_obj_gra2.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/d/actor/d_a_npc2.h b/include/d/actor/d_a_npc2.h index d1d06d7764..c940d14a87 100644 --- a/include/d/actor/d_a_npc2.h +++ b/include/d/actor/d_a_npc2.h @@ -119,8 +119,7 @@ public: public: /* 0x56C */ dBgS_ObjAcch mAcch; - /* 0x744 */ char field_0x744; - /* 0x745 */ u8 field_0x745[0x74c - 0x745]; + /* 0x744 */ char field_0x744[8]; /* 0x74C */ request_of_phase_process_class mPhase; /* 0x754 */ mDoExt_McaMorfSO* mpModelMorf; /* 0x758 */ Z2Creature mSound; diff --git a/src/d/actor/d_a_obj_gra2.cpp b/src/d/actor/d_a_obj_gra2.cpp index 58802a63ea..c57c9b372e 100644 --- a/src/d/actor/d_a_obj_gra2.cpp +++ b/src/d/actor/d_a_obj_gra2.cpp @@ -539,7 +539,7 @@ const char* daObj_GrA_c::getResName() { u8 daObj_GrA_c::getMode() { u32 uVar1 = fopAcM_GetParam(this) >> 28 & 3; - strcpy(&field_0x744, "Obj_grA"); + strcpy(field_0x744, "Obj_grA"); switch (uVar1) { case 1: From d0fa5f267574bf1e402a5b7fe4c497dcbe95ae1b Mon Sep 17 00:00:00 2001 From: Howard Luck Date: Sat, 11 Apr 2026 13:50:50 -0600 Subject: [PATCH 2/7] Fix daNpcCoach_Attr_c::field_0x28 array size (#3148) --- include/d/actor/d_a_npc_coach.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/d/actor/d_a_npc_coach.h b/include/d/actor/d_a_npc_coach.h index d5ee60e2cf..3917d6f11c 100644 --- a/include/d/actor/d_a_npc_coach.h +++ b/include/d/actor/d_a_npc_coach.h @@ -25,10 +25,7 @@ public: /* 0x1C */ f32 max_speed; // 最大速度 - Maximum Speed /* 0x20 */ f32 spring_constant; // バネ係数 - Spring Constant /* 0x24 */ f32 damp_coeff[1]; // 減衰係数 - Damp Coefficient - /* 0x28 */ f32 field_0x28[1]; - /* 0x2C */ f32 field_0x2c; - /* 0x30 */ f32 field_0x30; - /* 0x34 */ f32 field_0x34; + /* 0x28 */ f32 field_0x28[4]; /* 0x38 */ f32 vert_swing_width; // 縦揺れ幅 - Vertical Swing Width /* 0x3C */ f32 shake_dist; // 揺れ距離 - Shake Distance /* 0x40 */ f32 jump_dist; // 跳ね距離 - Jump Distance From ef23a2294c5426b3c3ef82519b36249bbbf08231 Mon Sep 17 00:00:00 2001 From: Howard Luck Date: Sat, 11 Apr 2026 13:51:20 -0600 Subject: [PATCH 3/7] Fix obj_maki_class::field_0x6f8 array size (#3149) --- include/d/actor/d_a_obj_maki.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/d/actor/d_a_obj_maki.h b/include/d/actor/d_a_obj_maki.h index c15b0b9ac1..aad8028e9c 100644 --- a/include/d/actor/d_a_obj_maki.h +++ b/include/d/actor/d_a_obj_maki.h @@ -28,11 +28,9 @@ public: /* 0x580 */ s16 field_0x580[2]; /* 0x584*/ dCcD_Stts mStts; /* 0x5c0 */ dCcD_Sph mSph; - /* 0x6f8 */ u32 field_0x6f8[4]; - /* 0x6fc */ u8 field_0x6fc[0x70c - 0x708]; // Undefined + /* 0x6f8 */ u32 field_0x6f8[5]; /* 0x70c */ LIGHT_INFLUENCE mLightObj; /* 0x72c */ u8 field_0x72c; - /* 0x72d */ u8 field_0x72d[0x730 - 0x72d]; //Undefined }; STATIC_ASSERT(sizeof(obj_maki_class) == 0x730); From 501f1c11d66ae94877f54d7dd49afab9fdc07a05 Mon Sep 17 00:00:00 2001 From: Howard Luck Date: Sat, 11 Apr 2026 13:52:48 -0600 Subject: [PATCH 4/7] Fix daE_FB_c::mKeys array size on PC (#3151) --- include/d/actor/d_a_e_fb.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/d/actor/d_a_e_fb.h b/include/d/actor/d_a_e_fb.h index 3e8734b8b6..a4494c5e7a 100644 --- a/include/d/actor/d_a_e_fb.h +++ b/include/d/actor/d_a_e_fb.h @@ -71,10 +71,16 @@ private: /* 0xA30 */ dCcD_Sph mSphere2; /* 0xB68 */ dCcD_Sph mAtSph; /* 0xCA0 */ dCcU_AtInfo mAtInfo; +#if AVOID_UB + /* 0xCC4 */ u32 mKeys[8]; + /* 0xCE4 */ u8 mHIOInit; + /* 0xCE5 */ u8 field_0xce5[0xCE8 - 0xCE5]; +#else // !@bug Seems that the orig developers didn't size mKeys correctly, as ideally it should be len=8, not len=7: /* 0xCC4 */ u32 mKeys[7]; /* 0xCE0 */ u8 mHIOInit; /* 0xCE1 */ u8 field_0xce1[0xCE8 - 0xCE1]; +#endif }; STATIC_ASSERT(sizeof(daE_FB_c) == 0xce8); From 83c6032c15194a75a9efffaa4a56e5c369d955c6 Mon Sep 17 00:00:00 2001 From: Howard Luck Date: Sat, 11 Apr 2026 13:53:51 -0600 Subject: [PATCH 5/7] Fix daE_VA_c::mRopeCutStatus and va_tag_* array sizes (#3152) --- include/d/actor/d_a_e_vt.h | 3 +-- src/d/actor/d_a_e_vt.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/d/actor/d_a_e_vt.h b/include/d/actor/d_a_e_vt.h index 5d6bf3dfd2..4b6082adae 100644 --- a/include/d/actor/d_a_e_vt.h +++ b/include/d/actor/d_a_e_vt.h @@ -159,8 +159,7 @@ private: /* 0x00958 */ mDoExt_3DlineMat1_c mRope; /* 0x00994 */ cXyz field_0x994[100]; /* 0x00E44 */ csXyz field_0xe44[100]; - /* 0x0109C */ u8 mRopeCutStatus[10]; - /* 0x010A6 */ u8 field_0x10A6[0x01100 - 0x010A6]; + /* 0x0109C */ u8 mRopeCutStatus[100]; /* 0x01100 */ u8 mDrawRopes; /* 0x01101 */ u8 field_0x1101[0x01104 - 0x01101]; /* 0x01104 */ f32 field_0x1104[10]; diff --git a/src/d/actor/d_a_e_vt.cpp b/src/d/actor/d_a_e_vt.cpp index a52b02e598..b0b7d42ab0 100644 --- a/src/d/actor/d_a_e_vt.cpp +++ b/src/d/actor/d_a_e_vt.cpp @@ -167,6 +167,30 @@ static dCcD_SrcSph cc_vt_magic_src = { } // mSphAttr }; +// !@bug The i<40 loops that index these arrays read one element past the end; on +// GC/Wii the OOB reads land on adjacent rodata instead of a defined value. +#if AVOID_UB +static u8 va_tag_set_size[40] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x00, +}; + +static u8 va_tag_set_num[40] = { + 0x01, 0x0C, 0x16, 0x1F, 0x21, 0x2A, 0x2B, 0x02, 0x04, 0x0D, 0x0F, 0x15, 0x18, + 0x20, 0x2C, 0x03, 0x05, 0x06, 0x0B, 0x10, 0x17, 0x19, 0x1A, 0x22, 0x24, 0x29, + 0x2D, 0x34, 0x49, 0x52, 0x36, 0x3E, 0x54, 0x5C, 0x39, 0x41, 0x4C, 0x56, 0x5E, + 0x00, +}; + +static f32 va_tag_offset[40] = { + 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 0.0f, 40.0f, 0.0f, 30.0f, 10.0f, 0.0f, 0.0f, 20.0f, + 0.0f, 10.0f, 20.0f, 40.0f, 0.0f, 20.0f, 0.0f, 0.0f, 20.0f, 0.0f, 10.0f, 0.0f, 0.0f, + 20.0f, 10.0f, 20.0f, 30.0f, 0.0f, 10.0f, 20.0f, 0.0f, 0.0f, 10.0f, 20.0f, 30.0f, 0.0f, + 0.0f, +}; +#else static u8 va_tag_set_size[39] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, @@ -184,6 +208,7 @@ static f32 va_tag_offset[39] = { 0.0f, 10.0f, 20.0f, 40.0f, 0.0f, 20.0f, 0.0f, 0.0f, 20.0f, 0.0f, 10.0f, 0.0f, 0.0f, 20.0f, 10.0f, 20.0f, 30.0f, 0.0f, 10.0f, 20.0f, 0.0f, 0.0f, 10.0f, 20.0f, 30.0f, 0.0f, }; +#endif } // namespace From 55122561b3ca6c521648783006ae16f9a7a3ef51 Mon Sep 17 00:00:00 2001 From: Howard Luck Date: Sat, 11 Apr 2026 13:54:25 -0600 Subject: [PATCH 6/7] Fix dMsgFlow_c::event027 aParam8 buffer size (#3153) --- src/d/d_msg_flow.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/d/d_msg_flow.cpp b/src/d/d_msg_flow.cpp index 4648f81dc9..47ef21063e 100644 --- a/src/d/d_msg_flow.cpp +++ b/src/d/d_msg_flow.cpp @@ -2229,7 +2229,13 @@ int dMsgFlow_c::event027(mesg_flow_node_event* i_flowNode_p, fopAc_ac_c* i_speak u16 prm0; getParam(&prm0, &prm1, i_flowNode_p->params); + // !@bug aParam8 is undersized; getParam always writes 4 bytes, stomping the + // 2 bytes past the buffer. Harmless on GC/Wii (MWCC stack layout absorbs it). +#if AVOID_UB + u8 aParam8[4]; +#else u8 aParam8[2]; +#endif getParam(aParam8, i_flowNode_p->params); JUT_ASSERT(4509, (aParam8[0] >= 0 && aParam8[0] <= dSv_player_item_c::BOMB_BAG_MAX) || (aParam8[0] == 4)); From b4ca7304a0349e1d3267d39cac603e87286cd3e7 Mon Sep 17 00:00:00 2001 From: TakaRikka <38417346+TakaRikka@users.noreply.github.com> Date: Mon, 13 Apr 2026 01:42:10 -0700 Subject: [PATCH 7/7] cat door cleanup (#3155) --- include/d/actor/d_a_obj_catdoor.h | 27 +++++++++-- src/d/actor/d_a_obj_catdoor.cpp | 75 +++++++++++++++++-------------- 2 files changed, 65 insertions(+), 37 deletions(-) diff --git a/include/d/actor/d_a_obj_catdoor.h b/include/d/actor/d_a_obj_catdoor.h index 78f5525d8c..dd7141d920 100644 --- a/include/d/actor/d_a_obj_catdoor.h +++ b/include/d/actor/d_a_obj_catdoor.h @@ -12,6 +12,27 @@ public: /* 0xf4 */ s16 angle; }; +class daObjCatDoor_Attr_c { +public: + /* 0x0 */ s16 speed; + /* 0x2 */ s16 decay_rate; +}; + +class daObjCatDoor_Hio_c : public mDoHIO_entry_c { +public: + daObjCatDoor_Hio_c(); + ~daObjCatDoor_Hio_c(); + + void genMessage(JORMContext*); + + void ct(); + void dt(); + void default_set(); + + /* 0x8 */ int field_0x8; + /* 0xC */ daObjCatDoor_Attr_c m_attr; +}; + /** * @ingroup actors-objects * @class daObjCatDoor_c @@ -24,7 +45,7 @@ class daObjCatDoor_c : public fopAc_ac_c { public: inline ~daObjCatDoor_c(); - const s16* attr() const; + const daObjCatDoor_Attr_c* attr() const; void initBaseMtx(); void setBaseMtx(); void calcOpen(); @@ -45,7 +66,7 @@ public: } void setDoorOpen() { - mRotSpeed = attr()[1]; + mRotSpeed = attr()->decay_rate; dBgW* bgw1 = &mDoor1.bgw; if (bgw1->ChkUsed()) { dComIfG_Bgsp().Release(bgw1); @@ -67,7 +88,7 @@ private: /* 0x790 */ s16 mRotSpeed; public: - static u32 const M_attr; + static const daObjCatDoor_Attr_c M_attr; }; #endif /* D_A_OBJ_CATDOOR_H */ diff --git a/src/d/actor/d_a_obj_catdoor.cpp b/src/d/actor/d_a_obj_catdoor.cpp index b513e70050..1be955b6c9 100644 --- a/src/d/actor/d_a_obj_catdoor.cpp +++ b/src/d/actor/d_a_obj_catdoor.cpp @@ -10,35 +10,38 @@ static const char* l_arcName = "CatDoor"; -u32 const daObjCatDoor_c::M_attr = 0x001E0578; +const daObjCatDoor_Attr_c daObjCatDoor_c::M_attr = { + 30, + 1400, +}; daObjCatDoor_c::~daObjCatDoor_c() { if (mDoor1.bgw.ChkUsed()) { dComIfG_Bgsp().Release(&mDoor1.bgw); } + if (mDoor2.bgw.ChkUsed()) { dComIfG_Bgsp().Release(&mDoor2.bgw); } + dComIfG_resDelete(&mPhaseReq, l_arcName); } int daObjCatDoor_c::createHeap() { J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes(l_arcName, 4); + JUT_ASSERT(174, modelData != NULL); - ASSERT(modelData != NULL); mDoor1.pmodel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084); mDoor2.pmodel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084); if (mDoor1.pmodel == NULL || mDoor2.pmodel == NULL) { return 0; } - cBgD_t* cbgd = (cBgD_t*)dComIfG_getObjectRes(l_arcName, 7); - if (mDoor1.bgw.Set(cbgd, 1, &mDoor1.mtx)) { + if (mDoor1.bgw.Set((cBgD_t*)dComIfG_getObjectRes(l_arcName, 7), 1, &mDoor1.mtx)) { return 0; } - cBgD_t* cbgd2 = (cBgD_t*)dComIfG_getObjectRes(l_arcName, 7); - if (mDoor2.bgw.Set(cbgd2, 1, &mDoor2.mtx)) { + if (mDoor2.bgw.Set((cBgD_t*)dComIfG_getObjectRes(l_arcName, 7), 1, &mDoor2.mtx)) { return 0; } @@ -48,9 +51,9 @@ int daObjCatDoor_c::createHeap() { int daObjCatDoor_c::draw() { g_env_light.settingTevStruct(0x10, ¤t.pos, &tevStr); - fopAc_ac_c* p1 = static_cast(this); - g_env_light.setLightTevColorType_MAJI(mDoor1.pmodel, &p1->tevStr); - g_env_light.setLightTevColorType_MAJI(mDoor2.pmodel, &p1->tevStr); + fopAc_ac_c* actor = (fopAc_ac_c*)this; + g_env_light.setLightTevColorType_MAJI(mDoor1.pmodel, &actor->tevStr); + g_env_light.setLightTevColorType_MAJI(mDoor2.pmodel, &actor->tevStr); dComIfGd_setListBG(); mDoExt_modelUpdateDL(mDoor1.pmodel); @@ -60,22 +63,22 @@ int daObjCatDoor_c::draw() { } int daObjCatDoor_c::execute() { - if (dComIfGs_isSwitch(fopAcM_GetParam(this) & 0xFF, fopAcM_GetHomeRoomNo(this)) || - mRotSpeed == 0) - { + if (fopAcM_isSwitch(this, getSwitchNo()) || mRotSpeed == 0) { return 1; } + calcOpen(); setBaseMtx(); return 1; } -const s16* daObjCatDoor_c::attr() const { - return (const s16*)&daObjCatDoor_c::M_attr; +const daObjCatDoor_Attr_c* daObjCatDoor_c::attr() const { + return &daObjCatDoor_c::M_attr; } -static int createSolidHeap(fopAc_ac_c* i_this) { - return static_cast(i_this)->createHeap(); +static int createSolidHeap(fopAc_ac_c* actor) { + daObjCatDoor_c* i_this = (daObjCatDoor_c*)actor; + return i_this->createHeap(); } int daObjCatDoor_c::create() { @@ -84,7 +87,7 @@ int daObjCatDoor_c::create() { int phase_state = dComIfG_resLoad(&mPhaseReq, l_arcName); if (phase_state == cPhs_COMPLEATE_e) { if (!fopAcM_entrySolidHeap(this, createSolidHeap, 0x2520)) { - phase_state = cPhs_ERROR_e; + return cPhs_ERROR_e; } else { create_init(); } @@ -93,7 +96,8 @@ int daObjCatDoor_c::create() { } void daObjCatDoor_c::create_init() { - ASSERT(getSwitchNo() != 0xff); + JUT_ASSERT(295, getSwitchNo() != 0xff); + fopAcM_setCullSizeBox(this, -200.0f, 0.0f, -20.0f, 200.0f, 260.0f, 100.0f); if (fopAcM_isSwitch(this, getSwitchNo())) { mDoor1.angle = 0x8800; @@ -106,37 +110,40 @@ void daObjCatDoor_c::create_init() { mDoor2.bgw.SetRoomId(fopAcM_GetRoomNo(this)); dComIfG_Bgsp().Regist(&mDoor2.bgw, this); } + initBaseMtx(); } void daObjCatDoor_c::initBaseMtx() { - cullMtx = mMtx; + fopAcM_SetMtx(this, mMtx); mDoMtx_stack_c::transS(current.pos); - mDoMtx_YrotM(mDoMtx_stack_c::get(), shape_angle.y); - mDoMtx_copy(mDoMtx_stack_c::get(), mMtx); + mDoMtx_stack_c::YrotM(shape_angle.y); + cMtx_copy(mDoMtx_stack_c::get(), mMtx); setBaseMtx(); } void daObjCatDoor_c::setBaseMtx() { mDoMtx_stack_c::transS(current.pos); - mDoMtx_YrotM(mDoMtx_stack_c::get(), shape_angle.y); + mDoMtx_stack_c::YrotM(shape_angle.y); + for (int i = 0; i < 2; i++) { daObjCatDoor_Door_c* door = i == 0 ? &mDoor1 : &mDoor2; f32 xOff = i == 0 ? -97.0f : 97.0f; s16 rot = i == 0 ? door->angle : s16(door->angle + 0x8000); + mDoMtx_stack_c::push(); mDoMtx_stack_c::transM(xOff, 0.0, 0.0); - mDoMtx_YrotM(mDoMtx_stack_c::get(), (s16)rot); - mDoMtx_copy(mDoMtx_stack_c::get(), door->pmodel->mBaseTransformMtx); - mDoMtx_copy(mDoMtx_stack_c::get(), door->mtx); + mDoMtx_stack_c::YrotM((s16)rot); + door->pmodel->setBaseTRMtx(mDoMtx_stack_c::get()); + cMtx_copy(mDoMtx_stack_c::get(), door->mtx); door->bgw.Move(); mDoMtx_stack_c::pop(); } } void daObjCatDoor_c::calcOpen() { - s16 prev = mRotSpeed; - int res = cLib_chaseS(&mRotSpeed, 0, *attr()); + s16 prev = (s16)mRotSpeed; + int res = cLib_chaseS(&mRotSpeed, 0, attr()->speed); for (int i = 0; i < 2; i++) { daObjCatDoor_Door_c* door = i == 0 ? &mDoor1 : &mDoor2; if (i == 0) { @@ -159,20 +166,20 @@ static int daObjCatDoor_Execute(daObjCatDoor_c* i_this) { return static_cast(i_this)->execute(); } -static bool daObjCatDoor_IsDelete(daObjCatDoor_c* i_this) { - return true; +static int daObjCatDoor_IsDelete(daObjCatDoor_c* i_this) { + return 1; } static int daObjCatDoor_Delete(daObjCatDoor_c* i_this) { - fopAcM_GetID(i_this); + fpc_ProcID id = fopAcM_GetID(i_this); i_this->~daObjCatDoor_c(); return 1; } -static int daObjCatDoor_Create(fopAc_ac_c* i_this) { - fopAcM_GetID(i_this); - daObjCatDoor_c* a_this = static_cast(i_this); - return a_this->create(); +static int daObjCatDoor_Create(fopAc_ac_c* actor) { + daObjCatDoor_c* i_this = (daObjCatDoor_c*)actor; + fpc_ProcID id = fopAcM_GetID(actor); + return i_this->create(); } static actor_method_class l_daObjCatDoor_Method = {