Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

d_a_msw #662

Merged
merged 15 commits into from
Jun 27, 2024
23 changes: 22 additions & 1 deletion include/d/actor/d_a_msw.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,31 @@
#define D_A_MSW_H

#include "f_op/f_op_actor.h"
#include "SSystem/SComponent/c_phase.h"
#include "d/d_bg_w.h"
#include "d/d_cc_d.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since dBgW is only used as a pointer, you can forward-declare it in the header.

class dBgW;


class msw_class : public fopAc_ac_c {
public:
/* Place member variables here */
/* 0x290 */ request_of_phase_process_class mPhs;
/* 0x298 */ s16 m298;
/* 0x29A */ s16 m29A;
/* 0x29C */ J3DModel* mpModel;
/* 0x2A0 */ u8 m2A0;
/* 0x2A4 */ cXyz m2A4;
/* 0x2B0 */ cXyz m2B0;
/* 0x2BC */ cXyz m2BC;
/* 0x2C8 */ csXyz m2C8;
/* 0x2D0 */ J3DModel* mpChainModels[4];
/* 0x2E0 */ cXyz m2E0[4];
/* 0x310 */ cXyz m310[4];
/* 0x340 */ dCcD_Stts mStts;
/* 0x37C */ dCcD_Cyl mChainCyls[4];
/* 0x83C */ s16 m83C[4];
/* 0x844 */ s16 m844;
/* 0x846 */ u8 m846[0x84C - 0x846]; // ?
/* 0x84C */ Mtx mMtx;
/* 0x87C */ dBgW* mpBgW;
};

#endif /* D_A_MSW_H */
326 changes: 308 additions & 18 deletions src/d/actor/d_a_msw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,342 @@
//

#include "d/actor/d_a_msw.h"
#include "d/res/res_msw.h"
#include "d/d_bg_w.h"
#include "d/d_bg_s_movebg_actor.h"
#include "d/d_procname.h"
#include "m_Do/m_Do_ext.h"
#include "d/d_com_inf_game.h"
#include "d/d_s_play.h"
#include "d/actor/d_a_player.h"

/* 00000078-000002D4 .text ride_call_back__FP4dBgWP10fopAc_ac_cP10fopAc_ac_c */
void ride_call_back(dBgW*, fopAc_ac_c*, fopAc_ac_c*) {
/* Nonmatching */
void ride_call_back(dBgW* bgw, fopAc_ac_c* i_ac, fopAc_ac_c* i_pt) {
msw_class* pActor = static_cast<msw_class*>(i_ac);

cMtx_YrotS(*calc_mtx, -i_ac->current.angle.y);

cXyz tmp = i_pt->current.pos - i_ac->current.pos;
cXyz pos1;
MtxPosition(&tmp, &pos1);
cXyz pos2;
tmp = i_pt->old.pos - i_ac->current.pos;
MtxPosition(&tmp, &pos2);

s16 z = pos1.z * ((g_regHIO.mChild[0].mFloatRegs[0] + 20.0f) / i_ac->scale.z);
s16 x = -pos1.x * ((g_regHIO.mChild[0].mFloatRegs[0] + 20.0f) / i_ac->scale.x);

cLib_addCalcAngleS2(&i_ac->current.angle.x, z, 10, 0x800);
cLib_addCalcAngleS2(&i_ac->current.angle.z, x, 10, 0x800);

f32 dist = (g_regHIO.mChild[0].mFloatRegs[4] + 50.0f) * fabsf(pos1.z - pos2.z);
if (pActor->m2BC.x < dist) {
pActor->m2BC.x = dist;
}

dist = (g_regHIO.mChild[0].mFloatRegs[4] + 50.0f) * fabsf(pos1.x - pos2.x);
if (pActor->m2BC.z < dist) {
pActor->m2BC.z = dist;
}

dist = (g_regHIO.mChild[0].mFloatRegs[8] + 5.0f) * fabsf(pos1.x - pos2.x);
if (dist > 10.0f && pActor->m2B0.x < dist) {
cLib_addCalc2(&pActor->m2B0.x, dist, 1.0f, g_regHIO.mChild[0].mFloatRegs[7] + 1.2f);
}

dist = (g_regHIO.mChild[0].mFloatRegs[8] + 5.0f) * fabsf(pos1.z - pos2.z);
if (dist > 10.0f && pActor->m2B0.z < dist) {
cLib_addCalc2(&pActor->m2B0.z, dist, 1.0f, g_regHIO.mChild[0].mFloatRegs[7] + 1.2f);
}

}

/* 00000310-00000540 .text chain_Draw__FP9msw_class */
void chain_Draw(msw_class*) {
/* Nonmatching */
void chain_Draw(msw_class* i_this) {
s16 angle1;
s32 angle2;

for (int i = 0; i < 4; i++) {
cXyz tmp = i_this->m310[i] - i_this->m2E0[i];
angle1 = -cM_atan2s(tmp.y, tmp.z);

// TODO: std::sqrtf(float)
angle2 = cM_atan2s(tmp.x, sqrtf(tmp.y * tmp.y + tmp.z * tmp.z));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the sqrtf not just tmp.absXZ()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not in the debug map.

I'm pretty sure that d_a_msw was written very early in development.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

absXZ calls VECSquareMag so it wouldn't match anyway.
I think the team that did the C-style actors never used absXZ since I've seen this sqrtf(x*x + z*z) written out manually a lot in them (maybe a macro?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

absXZ calls VECSquareMag so it wouldn't match anyway. I think the team that did the C-style actors never used absXZ since I've seen this sqrtf(x*x + z*z) written out manually a lot in them (maybe a macro?)

I find it unlikely that they used a macro since there's not really any benefit to using macros for that.

Copy link
Collaborator Author

@DanTGL DanTGL Jun 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And it doesn't really matter in this case. All three of us have apparently misread the code.


MtxTrans(i_this->m2E0[i].x, i_this->m2E0[i].y, i_this->m2E0[i].z, false);

s16 var_r4;
s32 var_r20;

if (i_this->m83C[i] != 0) {
var_r20 = i_this->m83C[i] * cM_ssin(i_this->m298 * 18000) * (g_regHIO.mChild[6].mFloatRegs[6] + 100.0f);
var_r4 = i_this->m298 * 3000;
} else {
var_r4 = 0;
var_r20 = 0;
}

cMtx_YrotM(*calc_mtx, var_r4);
cMtx_XrotM(*calc_mtx, angle1 + var_r20);
cMtx_YrotM(*calc_mtx, angle2);

i_this->mpChainModels[i]->setBaseTRMtx(*calc_mtx);
g_env_light.setLightTevColorType(i_this->mpChainModels[i], &i_this->tevStr);
mDoExt_modelUpdateDL(i_this->mpChainModels[i]);
}
}

/* 00000540-000005E8 .text daMsw_Draw__FP9msw_class */
static BOOL daMsw_Draw(msw_class*) {
/* Nonmatching */
static BOOL daMsw_Draw(msw_class* i_this) {
g_env_light.settingTevStruct(TEV_TYPE_BG0, &i_this->current.pos, &i_this->tevStr);
g_env_light.setLightTevColorType(i_this->mpModel, &i_this->tevStr);

mDoExt_modelUpdateDL(i_this->mpModel);

dComIfGd_setListBG();
chain_Draw(i_this);
dComIfGd_setList();

return TRUE;
}

/* 000005E8-0000080C .text msw_move__FP9msw_class */
void msw_move(msw_class*) {
/* Nonmatching */
void msw_move(msw_class* i_this) {
i_this->m298 += 1;

// WTH?
// Branchless comparison
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably something #ifdef'd out for debug

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other than a switch statement, another way to get MWCC to generate a branchless comparison is with this trick using a self-assign on any float member variable that gets optimized out:

    if (i_this->m29A == 0) {
        i_this->speedF = i_this->speedF;
    }

but without knowing what i_this->m29A there's no way to know what they actually wrote

switch (i_this->m29A) {
case 0:
break;
}

cLib_addCalcAngleS2(&i_this->current.angle.x, 0, 10, 0x200);
cLib_addCalcAngleS2(&i_this->current.angle.z, 0, 10, 0x200);

i_this->m2C8.x = i_this->m2BC.x * cM_ssin(i_this->m298 * 1500);
i_this->m2C8.z = i_this->m2BC.z * cM_ssin(i_this->m298 * 1300);

cLib_addCalc2(&i_this->m2BC.x, g_regHIO.mChild[0].mFloatRegs[9], 1.0f, g_regHIO.mChild[0].mFloatRegs[3] + 20.0f);
cLib_addCalc2(&i_this->m2BC.z, g_regHIO.mChild[0].mFloatRegs[9], 1.0f, g_regHIO.mChild[0].mFloatRegs[3] + 20.0f);

i_this->m2A4.x = i_this->m2B0.x * cM_ssin(i_this->m298 * 750);
i_this->m2A4.z = i_this->m2B0.z * cM_ssin(i_this->m298 * 900);

cLib_addCalc0(&i_this->m2B0.x, 1.0f, g_regHIO.mChild[0].mFloatRegs[6] + 0.25f);
cLib_addCalc0(&i_this->m2B0.z, 1.0f, g_regHIO.mChild[0].mFloatRegs[6] + 0.25f);

i_this->shape_angle = i_this->current.angle + i_this->m2C8;
i_this->current.pos = i_this->home.pos + i_this->m2A4;
}

/* 0000080C-00000AD4 .text daMsw_Execute__FP9msw_class */
static BOOL daMsw_Execute(msw_class*) {
/* Nonmatching */
static BOOL daMsw_Execute(msw_class* i_this) {
static f32 xd[4] = { 1.0f, 1.0f, -1.0f, -1.0f };
static f32 zd[4] = { 1.0f, -1.0f, 1.0f, -1.0f };

daPy_py_c* pPlayer = static_cast<daPy_py_c*>(dComIfGp_getPlayer(0));
msw_move(i_this);

MtxTrans(i_this->current.pos.x, i_this->current.pos.y, i_this->current.pos.z, false);
cMtx_YrotM(*calc_mtx, i_this->shape_angle.y);
cMtx_XrotM(*calc_mtx, i_this->shape_angle.x);
cMtx_ZrotM(*calc_mtx, i_this->shape_angle.z);
MtxScale(i_this->scale.x, 1.0f, i_this->scale.z, true);

i_this->mpModel->setBaseTRMtx(*calc_mtx);
MtxPush();

for (int chainIdx = 0; chainIdx < 4; chainIdx++) {
f32 tmp = 200.0f + g_regHIO.mChild[0].mFloatRegs[10];
cXyz src;
src.x = tmp * xd[chainIdx];
src.y = 0.0f;
src.z = tmp * zd[chainIdx];
MtxPosition(&src, &i_this->m2E0[chainIdx]);

if (i_this->m844 != 0) {
i_this->m844 -= 1;
i_this->m310[chainIdx] = i_this->m2E0[chainIdx];
i_this->m310[chainIdx].y = i_this->m2E0[chainIdx].y + 1000.0f;
}

if (i_this->m83C[chainIdx] != 0) {
i_this->m83C[chainIdx] -= 1;
}

if (i_this->mChainCyls[chainIdx].ChkTgHit() && i_this->m83C[chainIdx] < 10) {
i_this->m83C[chainIdx] = g_regHIO.mChild[6].mShortRegs[3] + 0xF;

mDoAud_seStart(JA_SE_LK_HIT_SBRIDGE_CHAIN, &i_this->m2E0[chainIdx], 0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this)));

cXyz scale;
scale.z = 2.0f;
scale.y = 2.0f;
scale.x = 2.0f;

dComIfGp_particle_set(dPa_name::ID_COMMON_PURPLE_HIT, i_this->mChainCyls[chainIdx].GetTgHitPosP(), &pPlayer->shape_angle, &scale);
}
i_this->mChainCyls[chainIdx].SetC(i_this->m2E0[chainIdx]);

dComIfG_Ccsp()->Set(&i_this->mChainCyls[chainIdx]);
}

MtxPull();
MTXCopy(*calc_mtx, i_this->mMtx);
i_this->mpBgW->Move();

return TRUE;
}

/* 00000AD4-00000B38 .text daMsw_IsDelete__FP9msw_class */
static BOOL daMsw_IsDelete(msw_class*) {
/* Nonmatching */
static BOOL daMsw_IsDelete(msw_class* i_this) {
for (int i = 0; i < 4; i++) {
mDoAud_seDeleteObject(&i_this->m2E0[i]);
}

return TRUE;
}

/* 00000B38-00000B88 .text daMsw_Delete__FP9msw_class */
static BOOL daMsw_Delete(msw_class*) {
/* Nonmatching */
static BOOL daMsw_Delete(msw_class* i_this) {
dComIfG_resDelete(&i_this->mPhs, "Msw");
dComIfG_Bgsp()->Release(i_this->mpBgW);

return TRUE;
}

/* 00000B88-00000D3C .text daMsw_CreateInit__FP10fopAc_ac_c */
void daMsw_CreateInit(fopAc_ac_c*) {
/* Nonmatching */
BOOL daMsw_CreateInit(fopAc_ac_c* i_this) {
msw_class* pActor = static_cast<msw_class*>(i_this);

J3DModelData* modelData = static_cast<J3DModelData*>(dComIfG_getObjectRes("Msw", MSW_BDL_MSWNG));
pActor->mpModel = mDoExt_J3DModel__create(modelData, 0, 0x11020203);

if (pActor->mpModel == NULL) {
return FALSE;
}

modelData = static_cast<J3DModelData*>(dComIfG_getObjectRes("Msw", MSW_BDL_OBM_CHAIN1));
JUT_ASSERT(0x20B, modelData != NULL);

for (int chainIdx = 0; chainIdx < 4; chainIdx++) {
pActor->mpChainModels[chainIdx] = mDoExt_J3DModel__create(modelData, 0, 0x11020203);
if (pActor->mpChainModels[chainIdx] == NULL) {
return FALSE;
}
}

pActor->mpBgW = new dBgW();

if (pActor->mpBgW == NULL) {
return FALSE;
}

cBgD_t* pBgd = static_cast<cBgD_t*>(dComIfG_getObjectRes("Msw", MSW_DZB_MSWING));

if ((BOOL)pActor->mpBgW->Set(pBgd, cBgW::MOVE_BG_e, &pActor->mMtx) == TRUE) {
return FALSE;
}

pActor->mpBgW->SetCrrFunc(dBgS_MoveBGProc_Typical);
pActor->mpBgW->SetRideCallback(ride_call_back);

return TRUE;
}

/* 00000D3C-00000FE0 .text daMsw_Create__FP10fopAc_ac_c */
static s32 daMsw_Create(fopAc_ac_c*) {
/* Nonmatching */
static s32 daMsw_Create(fopAc_ac_c* i_this) {
static dCcD_SrcCyl himo_cyl_src = {
// dCcD_SrcGObjInf
{
/* Flags */ 0,
/* SrcObjAt Type */ 0,
/* SrcObjAt Atp */ 0,
/* SrcObjAt SPrm */ 0,
/* SrcObjTg Type */ ~(AT_TYPE_WATER | AT_TYPE_UNK20000 | AT_TYPE_WIND | AT_TYPE_UNK400000 | AT_TYPE_LIGHT),
/* SrcObjTg SPrm */ TG_SPRM_SET | TG_SPRM_IS_ENEMY,
/* SrcObjCo SPrm */ CO_SPRM_SET | CO_SPRM_IS_UNK4 | CO_SPRM_VSGRP,
/* SrcGObjAt Se */ 0,
/* SrcGObjAt HitMark */ 0,
/* SrcGObjAt Spl */ 0,
/* SrcGObjAt Mtrl */ 0,
/* SrcGObjAt SPrm */ 0,
/* SrcGObjTg Se */ 0,
/* SrcGObjTg HitMark */ 0,
/* SrcGObjTg Spl */ 0,
/* SrcGObjTg Mtrl */ 0,
/* SrcGObjTg SPrm */ G_TG_SPRM_SHIELD,
/* SrcGObjCo SPrm */ 0,
},
// cM3dGCylS
{
/* Center */ 0.0f, 0.0f, 0.0f,
/* Radius */ 10.0f,
/* Height */ 1000.0f,
},
};

fopAcM_SetupActor(i_this, msw_class);
msw_class* pActor = static_cast<msw_class*>(i_this);

s32 phase_state = dComIfG_resLoad(&pActor->mPhs, "Msw");

if (phase_state == cPhs_COMPLEATE_e) {
pActor->m2A0 = (fopAcM_GetParam(pActor) >> 0) & 0xFF;

if (pActor->m2A0 == 0xFF) {
pActor->m2A0 = 0;
}

if (!fopAcM_entrySolidHeap(pActor, daMsw_CreateInit, 0x10040)) {
return cPhs_ERROR_e;
}

if (pActor->mpModel == NULL) {
return cPhs_ERROR_e;
}

if (dComIfG_Bgsp()->Regist(pActor->mpBgW, pActor)) {
return cPhs_ERROR_e;
}

switch (pActor->m2A0) {
case 1:
pActor->scale.x = 1.5f;
pActor->scale.z = 1.5f;
break;
case 2:
pActor->scale.x = 2.0f;
pActor->scale.z = 2.0f;
break;
case 3:
pActor->scale.x = 3.0f;
pActor->scale.z = 3.0f;
break;
default:
pActor->scale.z = 1.0f;
pActor->scale.x = 1.0f;
break;
}

pActor->scale.y = 1.0f;
fopAcM_SetMtx(pActor, pActor->mpModel->getBaseTRMtx());
fopAcM_SetMin(pActor, pActor->scale.x * -200.0f, -5000.0f, pActor->scale.z * -200.0f);
fopAcM_SetMax(pActor, pActor->scale.x * 200.0f, 5000.0f, pActor->scale.z * 200.0f);

pActor->mStts.Init(0xFF, 0xFF, pActor);

for (int chainIdx = 0; chainIdx < 4; chainIdx++) {
pActor->mChainCyls[chainIdx].Set(himo_cyl_src);
pActor->mChainCyls[chainIdx].SetStts(&pActor->mStts);
}

pActor->m844 = 10;
daMsw_Execute(pActor);
}

return phase_state;
}

static actor_method_class l_daMsw_Method = {
Expand Down