Files
dusklight/src/d/actor/d_a_mant.cpp
T
SuperDude88 511721f4d5 Fix Ganondorf's Cape Texture (#2016)
* Cape Texture Fix

- Load pos/norm/texcoord data directly from the REL

Before the hardcoded array was LE but being treated as BE, now we load it directly from the REL so treating it as BE is the correct behavior

* Fix Cape Tearing

- Update the cached textures when the cape is torn, reset the texture when creating the actor
2026-06-07 21:14:10 -06:00

805 lines
26 KiB
C++

/**
* @file d_a_mant.cpp
*
*/
#include "d/dolzel_rel.h" // IWYU pragma: keep
#include "d/actor/d_a_mant.h"
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
#include "d/actor/d_a_b_gnd.h"
#include "d/d_com_inf_game.h"
#if TARGET_PC
#include "dusk/dvd_asset.hpp"
#include "dusk/frame_interpolation.h"
using GameVersion = dusk::version::GameVersion;
// keep the original version of the cape texture const so we don't need to reload the file
static u8 const * l_Egnd_mantTEX_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x1C00}, {GameVersion::GcnPal, 0x1C00}}, 0x4000), true); return buf; }
static u8* l_Egnd_mantTEX_U_get() { alignas(32) static u8 buf[0x4000]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x5C00}, {GameVersion::GcnPal, 0x5C00}}, 0x4000), true); return buf; }
static u8* l_Egnd_mantPAL_get() { alignas(32) static u8 buf[0x60]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x9C00}, {GameVersion::GcnPal, 0x9C00}}, 0x60), true); return buf; }
#define l_Egnd_mantTEX (l_Egnd_mantTEX_get())
#define l_Egnd_mantTEX_U (l_Egnd_mantTEX_U_get())
#define l_Egnd_mantPAL (l_Egnd_mantPAL_get())
// make a copy of the cape texture that can be overwritten with the tears
static u8 l_Egnd_mantTEX_copy[0x4000];
// keep our cached texture objects out here so that we can update them from multiple places
static bool textureObjsInitialized = false;
static TGXTlutObj tlutObj;
static TGXTexObj mainTexObj;
static TGXTexObj undersideTexObj;
// l_pos is unused
//static f32* l_pos_get() { alignas(32) static f32 buf[507]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA44C}, {GameVersion::GcnPal, 0xA44C}}, sizeof(buf)), true); return buf; }
static f32* l_normal_get() { alignas(32) static f32 buf[3]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0x9C60}, {GameVersion::GcnPal, 0x9C60}}, sizeof(buf)), true); return buf; }
static f32* l_texCoord_get() { alignas(32) static f32 buf[338]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA458}, {GameVersion::GcnPal, 0xA458}}, sizeof(buf)), true); return buf; }
//#define l_pos (l_pos_get())
#define l_normal (l_normal_get())
#define l_texCoord (l_texCoord_get())
#else
#include "assets/l_Egnd_mantTEX.h"
#include "assets/l_Egnd_mantTEX_U.h"
#include "assets/l_Egnd_mantPAL.h"
#endif
#include "d/d_s_play.h"
#if TARGET_PC
using GameVersion = dusk::version::GameVersion;
static u8* l_Egnd_mantDL_get() { alignas(32) static u8 buf[0x3EC]; static bool _ = (dusk::LoadRelAsset(buf, "/rel/Final/Release/d_a_mant.rel", {{GameVersion::GcnUsa, 0xA9A0}, {GameVersion::GcnPal, 0xA9A0}}, 0x3EC), true); return buf; }
#define l_Egnd_mantDL (l_Egnd_mantDL_get())
#else
#include "assets/l_Egnd_mantDL.h"
#endif
#if !TARGET_PC
static void* pal_d = (void*)&l_Egnd_mantPAL;
static void* tex_d[2] = {
(void*)&l_Egnd_mantTEX,
(void*)&l_Egnd_mantTEX_U,
};
#endif
static char lbl_277_bss_0;
#if TARGET_PC
static void mant_build_anchor_frame(const cXyz& anchor_a, const cXyz& anchor_b, Mtx out) {
cXyz axis_x = anchor_b - anchor_a;
if (!axis_x.normalizeRS()) {
axis_x = cXyz::BaseX;
}
cXyz helper = fabsf(axis_x.y) > 0.95f ? cXyz::BaseZ : cXyz::BaseY;
cXyz axis_z = axis_x.getCrossProduct(helper);
if (!axis_z.normalizeRS()) {
axis_z = cXyz::BaseZ;
}
cXyz axis_y = axis_z.getCrossProduct(axis_x);
if (!axis_y.normalizeRS()) {
axis_y = cXyz::BaseY;
}
const cXyz center = anchor_a + ((anchor_b - anchor_a) * 0.5f);
const cXyz col[3] = { axis_x, axis_y, axis_z };
const f32 t[3] = { center.x, center.y, center.z };
for (int r = 0; r < 3; ++r) {
out[r][0] = (&col[0].x)[r];
out[r][1] = (&col[1].x)[r];
out[r][2] = (&col[2].x)[r];
out[r][3] = t[r];
}
}
#endif
void daMant_packet_c::draw() {
ZoneScoped;
#if TARGET_PC
void* image = l_Egnd_mantTEX_copy;
void* lut = l_Egnd_mantPAL;
#else
void* image = tex_d[0];
void* lut = pal_d;
#endif
j3dSys.reinitGX();
GXSetNumIndStages(0);
dKy_setLight_again();
dKy_GxFog_tevstr_set(this->mTevStr);
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_F32, 0);
#if TARGET_PC
cXyz* draw_pos = &this->mNrm[0][0];
{
const u8 curr_buffer = this->field_0x74;
const cXyz* curr_pos = &this->mPos[curr_buffer][0];
const MtxP curr_frame = curr_buffer == 0 ? this->mMtx : this->mMtx2;
Mtx curr_frame_inverse;
MTXInverse(curr_frame, curr_frame_inverse);
const u8 prev_buffer = curr_buffer ^ 1;
const cXyz* prev_pos = &this->mPos[prev_buffer][0];
Mtx prev_frame_inverse;
MTXInverse(prev_buffer == 0 ? this->mMtx : this->mMtx2, prev_frame_inverse);
Mtx presented_frame;
MTXCopy(curr_frame, presented_frame);
mant_class* mant_p = reinterpret_cast<mant_class*>(reinterpret_cast<u8*>(this) - offsetof(mant_class, field_0x0570));
if (mant_p != NULL) {
b_gnd_class* parent = (b_gnd_class*)fopAcM_SearchByID(mant_p->parentActorID);
if (parent != NULL && parent->mpModelMorf != NULL) {
J3DModel* model = parent->mpModelMorf->getModel();
if (model != NULL) {
MtxP src34 = model->getAnmMtx(34);
MtxP src25 = model->getAnmMtx(25);
Mtx joint_34_scratch;
Mtx joint_25_scratch;
MtxP joint_34 = dusk::frame_interp::lookup_replacement(src34, joint_34_scratch) ? joint_34_scratch : src34;
MtxP joint_25 = dusk::frame_interp::lookup_replacement(src25, joint_25_scratch) ? joint_25_scratch : src25;
cXyz presented_anchor_a;
cXyz presented_anchor_b;
cXyz local_offset;
MTXCopy(joint_34, *calc_mtx);
local_offset.set(10.0f, 5.0f, -17.0f);
MtxPosition(&local_offset, &presented_anchor_a);
MTXCopy(joint_25, *calc_mtx);
local_offset.set(10.0f, 5.0f, 17.0f);
MtxPosition(&local_offset, &presented_anchor_b);
mant_build_anchor_frame(presented_anchor_a, presented_anchor_b, presented_frame);
}
}
}
const f32 step = dusk::frame_interp::get_interpolation_step();
for (int i = 0; i < 169; ++i) {
cXyz curr_local;
MTXMultVec(curr_frame_inverse, &curr_pos[i], &curr_local);
cXyz prev_local;
MTXMultVec(prev_frame_inverse, &prev_pos[i], &prev_local);
cXyz local = prev_local + ((curr_local - prev_local) * step);
MTXMultVec(presented_frame, &local, &draw_pos[i]);
}
}
GXSETARRAY(GX_VA_POS, draw_pos, sizeof(mNrm[0]), 12, true);
GXSETARRAY(GX_VA_NRM, l_normal, sizeof(f32) * 3, 12, false);
#else
GXSETARRAY(GX_VA_POS, this->getPos(), sizeof(mPos[0]), 12, true);
GXSETARRAY(GX_VA_NRM, this->getNrm(), sizeof(mNrm[0]), 12, true);
#endif
GXSETARRAY(GX_VA_TEX0, l_texCoord, sizeof(f32) * 338, 8, false);
GXSetZCompLoc(0);
GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE);
GXSetNumChans(1);
GXSetChanCtrl(GX_COLOR0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, 0xff, GX_DF_CLAMP, GX_AF_SPOT);
GXSetNumTexGens(1);
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c);
GXSetNumTevStages(1);
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
dKy_Global_amb_set(this->mTevStr);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GXSetTevColor(GX_TEVREG0, COMPOUND_LITERAL(GXColor){1, 0, 0, 0});
GXSetTevKColor(GX_KCOLOR0, COMPOUND_LITERAL(GXColor){1, 0, 0, 0});
GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0);
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_KONST, GX_CC_TEXC, GX_CC_RASC, GX_CC_C0);
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_4, GX_TRUE, GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_KONST, GX_CA_TEXA, GX_CA_ZERO);
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K3_A);
GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0);
#if TARGET_PC
if (!textureObjsInitialized) {
GXInitTlutObj(&tlutObj, lut, GX_TL_RGB5A3, 0x100);
GXInitTexObjCI(&mainTexObj, image, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0);
GXInitTexObjLOD(&mainTexObj, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
GXInitTexObjCI(
&undersideTexObj, l_Egnd_mantTEX_U, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0);
GXInitTexObjLOD(&undersideTexObj, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
textureObjsInitialized = true;
}
#else
GXTlutObj GStack_80;
GXInitTlutObj(&GStack_80, lut, GX_TL_RGB5A3, 0x100);
TGXTexObj GStack_74;
GXInitTexObjCI(&GStack_74, image, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0);
GXInitTexObjLOD(&GStack_74, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
#endif
#if TARGET_PC
GXLoadTlut(&tlutObj, GX_TLUT0);
GXLoadTexObj(&mainTexObj, GX_TEXMAP0);
#else
GXLoadTlut(&GStack_80, GX_TLUT0);
GXLoadTexObj(&GStack_74, GX_TEXMAP0);
#endif
GXSetCullMode(GX_CULL_BACK);
Mtx MStack_54;
#if TARGET_PC
GXLoadPosMtxImm(j3dSys.getViewMtx(), GX_PNMTX0);
cMtx_inverseTranspose(j3dSys.getViewMtx(), MStack_54);
#else
GXLoadPosMtxImm(this->mMtx, GX_PNMTX0);
cMtx_inverseTranspose(this->mMtx, MStack_54);
#endif
GXLoadNrmMtxImm(MStack_54, GX_PNMTX0);
GXCallDisplayList(l_Egnd_mantDL, 0x3e0);
#if TARGET_PC
GXLoadTexObj(&undersideTexObj, GX_TEXMAP0);
#else
GXInitTexObjCI(&GStack_74, l_Egnd_mantTEX_U, 0x80, 0x80, GX_TF_C8, GX_CLAMP, GX_CLAMP, 0, 0);
GXInitTexObjLOD(&GStack_74, GX_LINEAR, GX_LINEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
GXLoadTexObj(&GStack_74, GX_TEXMAP0);
#endif
GXSetTevColor(GX_TEVREG0, COMPOUND_LITERAL(GXColor){0, 0, 0, 0});
GXSetTevKColor(GX_KCOLOR0, COMPOUND_LITERAL(GXColor){0, 0, 0, 0});
GXSetCullMode(GX_CULL_FRONT);
#if TARGET_PC
GXLoadPosMtxImm(j3dSys.getViewMtx(), GX_PNMTX0);
cMtx_inverseTranspose(j3dSys.getViewMtx(), MStack_54);
#else
GXLoadPosMtxImm(this->mMtx2, GX_PNMTX0);
cMtx_inverseTranspose(this->mMtx2, MStack_54);
#endif
GXLoadNrmMtxImm(MStack_54, GX_PNMTX0);
GXCallDisplayList(l_Egnd_mantDL, 0x3e0);
this->field_0x74 = lbl_277_bss_0 & 1;
J3DShape::resetVcdVatCache();
}
static int daMant_Draw(mant_class* i_this) {
g_env_light.settingTevStruct(0, &i_this->current.pos, &i_this->tevStr);
#if !TARGET_PC
MtxTrans(0.0f, 0.0f, 0.0f, 0.0f);
cMtx_concat(j3dSys.getViewMtx(), *calc_mtx, i_this->field_0x0570.getMtx());
cMtx_concat(j3dSys.getViewMtx(), *calc_mtx, i_this->field_0x0570.getMtx2());
#endif
i_this->field_0x0570.setTevStr(&i_this->tevStr);
j3dSys.getDrawBuffer(0)->entryImm(&i_this->field_0x0570, 0);
return 1;
}
static void joint_control(mant_class* i_this, mant_j_s* param_2, int param_3, f32 param_4, f32 param_5) {
static f32 d_p[12] = {
1.4000001f, 0.6f, 0.35f, 0.3f, 0.3f, 0.3f, 0.25f, 0.2f, 0.2f, 0.2f, 0.15f, 0.1f
};
mant_class* mant_sp38 = i_this;
cXyz spFC;
cXyz spF0;
cXyz spE4;
int sp34;
f32 sp30;
f32 sp2C;
f32 sp28;
cXyz* var_r30;
cXyz* sp24;
BOOL sp20 = FALSE;
cXyz spD8;
Vec spCC;
b_gnd_class* gndActor = (b_gnd_class*)fopAcM_SearchByID(mant_sp38->parentActorID);
f32 var_f31;
f32 var_f30;
f32 var_f29;
f32 var_f28;
f32 var_f27;
f32 var_f26;
f32 sp18;
f32 sp14;
if (gndActor->mDrawHorse != 0) {
sp20 = TRUE;
spD8 = gndActor->field_0x1fb8;
} else if (i_this->field_0x3966 != 0) {
spD8 = i_this->field_0x3928[0] + ((i_this->field_0x3928[1] - i_this->field_0x3928[0]) * 0.5f);
spD8.y += -60.0f + KREG_F(11);
}
var_r30 = param_2->field_0x0;
sp24 = param_2->field_0x9c;
dBgS_GndChk(sp108);
spCC = param_2->field_0x0[0];
spCC.y += 50.0f;
sp108.SetPos(&spCC);
var_f27 = dComIfG_Bgsp().GroundCross(&sp108) + 3.0f;
if (var_f27 - var_r30[0].y > 50.0f) {
var_f27 = var_r30[0].y;
}
cXyz spC0;
cXyz spB4;
cXyz spA8(0.0f, 0.0f, 0.0f);
cXyz sp9C(0.0f, 0.0f, 0.0f);
cXyz sp90(0.0f, 0.0f, 0.0f);
cMtx_YrotS(*calc_mtx, param_2->field_0x013a);
spFC.x = 0.0f;
spFC.y = 0.0f;
spFC.z = i_this->field_0x3954 * (cM_ssin(param_3 * 23000) * 0.05f + 1.0f);
MtxPosition(&spFC, &spC0);
cXyz sp84;
s16 sp0C;
s16 sp0A;
s16 sp08 = param_3 + -6;
if (sp08 < 0) {
sp08 *= -1;
}
ANGLE_MULT(sp08, -4000 + VREG_S(5));
spFC.x = 0.0f;
spFC.y = 0.0f;
spFC.z = i_this->field_0x394c;
spFC.z *= i_this->scale.y;
for (sp34 = 0; sp34 < 13; sp34++, var_r30++, sp24++) {
if (0 < sp34) {
sp14 = i_this->field_0x3950;
spB4 = spC0 * (d_p[sp34 - 1] + NREG_F(sp34));
sp18 = i_this->field_0x3958;
sp18 *= 1.0f + VREG_F(0) - sp34 * (0.07f + VREG_F(1));
sp84.zero();
// (1.0f / 100.0f)
if (param_4 > 0.01f) {
sp14 = 0.0f + VREG_F(15);
var_f26 = param_4 * (sp34 * (0.2f + VREG_F(16)) + 1.0f);
cMtx_YrotS(*calc_mtx, param_2->field_0x013a);
cMtx_XrotM(*calc_mtx, param_2->field_0x0138);
spF0.x = ((2.0f + VREG_F(17)) * var_f26) *
cM_ssin(i_this->field_0x25a0 * (0x1000 + JREG_S(0)) +
(sp34 * (-7500 + JREG_S(1))) + sp08);
spF0.y = ((5.0f + VREG_F(18)) * var_f26) *
cM_ssin(i_this->field_0x25a0 * (0x1800 + JREG_S(2)) +
(sp34 * (-7000 + JREG_S(3))) + sp08);
spF0.z = -15.0f + VREG_F(19);
MtxPosition(&spF0, &sp84);
}
if (param_5 > 0.01f) {
var_f26 = param_5 * (sp34 * (0.2f + VREG_F(16)) + 1.0f);
cMtx_YrotS(*calc_mtx, param_2->field_0x013a + -6000);
cMtx_XrotM(*calc_mtx, -5000);
spF0.x = ((2.0f + VREG_F(17)) * var_f26) *
cM_ssin(i_this->field_0x25a0 * (0x448 + JREG_S(0)) +
(sp34 * (-7000 + JREG_S(1))) + sp08);
spF0.y = ((6.0f + VREG_F(18)) * var_f26) *
cM_ssin(i_this->field_0x25a0 * (0xc48 + JREG_S(2)) +
(sp34 * (-7500 + JREG_S(3))) + sp08);
spF0.z = (-15.0f + VREG_F(19)) * param_5;
MtxPosition(&spF0, &spE4);
sp84 += spE4;
}
if (i_this->field_0x3960 > 0.1f) {
sp84.y = i_this->field_0x3960 *
cM_ssin(i_this->field_0x25a0 * (0x1100 + JREG_S(2)) +
(sp34 * (-7000 + JREG_S(3))) + sp08);
}
sp30 = (var_r30->x - var_r30[-1].x) + sp24->x + spB4.x + sp84.x;
sp28 = (var_r30->z - var_r30[-1].z) + sp24->z + spB4.z + sp84.z;
var_f31 = var_r30->y + sp24->y + sp18 + sp84.y;
if (sp20) {
var_f30 = var_f27;
spE4 = spD8 - *var_r30;
var_f29 = JMAFastSqrt(spE4.x * spE4.x + spE4.z * spE4.z);
var_f28 = 85.0f + KREG_F(12);
if (var_f29 < var_f28) {
var_f30 = spD8.y + 1.0f * JMAFastSqrt(var_f28 * var_f28 - var_f29 * var_f29) *
(1.0f + KREG_F(13));
}
if (var_f31 < var_f30) {
var_f31 = var_f30;
}
} else if (i_this->field_0x3966 != 0) {
var_f30 = var_f27;
spE4 = spD8 - *var_r30;
var_f29 = JMAFastSqrt(spE4.x * spE4.x + spE4.z * spE4.z);
var_f28 = 85.0f + KREG_F(12);
if (var_f29 < var_f28) {
var_f30 = spD8.y + JMAFastSqrt(var_f28 * var_f28 - var_f29 * var_f29) *
(1.0f + KREG_F(13));
}
if (var_f31 < var_f30) {
var_f31 = var_f30;
}
} else {
if (var_f31 < var_f27) {
var_f31 = var_f27;
}
}
sp2C = var_f31 - var_r30[-1].y;
sp0C = -cM_atan2s(sp2C, sp28);
sp0A = (s16)cM_atan2s(sp30, JMAFastSqrt(sp2C * sp2C + sp28 * sp28));
cMtx_XrotS(*calc_mtx, sp0C);
cMtx_YrotM(*calc_mtx, sp0A);
MtxPosition(&spFC, &spE4);
*sp24 = *var_r30;
var_r30->x = var_r30[-1].x + spE4.x;
var_r30->y = var_r30[-1].y + spE4.y;
var_r30->z = var_r30[-1].z + spE4.z;
sp24->x = sp14 * (var_r30->x - sp24->x);
sp24->y = sp14 * (var_r30->y - sp24->y);
sp24->z = sp14 * (var_r30->z - sp24->z);
}
}
}
static void mant_v_calc(mant_class* i_this) {
cXyz local_e4, cStack_f0, local_fc, local_108;
f32 dVar16, dVar15, dVar14, uVar15;
csXyz local_134(0, 0, 0);
mant_j_s* mantJS;
local_fc = i_this->field_0x3928[0] - i_this->field_0x3928[1];
local_134.y = cM_atan2s(local_fc.x, local_fc.z) + 0x4000;
mantJS = i_this->field_0x25a8;
local_e4.x = 0.0f;
dVar16 = local_fc.x / 12.0f;
dVar15 = local_fc.y / 12.0f;
dVar14 = local_fc.z / 12.0f;
local_108 = (i_this->current.pos - i_this->field_0x3940) * 0.9f;
if (local_108.abs() < 10.0f) {
uVar15 = 0.0f;
} else {
local_134.y = cM_atan2s(local_108.x, local_108.z);
local_134.x = -cM_atan2s(local_108.y, JMAFastSqrt(local_108.x * local_108.x + local_108.z * local_108.z));
if (i_this->field_0x3964 != 0) {
uVar15 = 4.0f;
i_this->field_0x3964 = 0;
} else {
uVar15 = 1.0f;
}
}
f32 uVar14 = 0.0f;
if (i_this->field_0x3965 == 0) {
if (i_this->field_0x3969 == 1) {
uVar14 = (1.0f / 5.0f);
} else if (i_this->field_0x3969 == 2) {
uVar14 = 0.6f;
} else if (i_this->field_0x3969 == 3) {
uVar14 = (7.0f / 100.0f);
}
}
for (int i = 0; i < 13; i++, mantJS++) {
i_this->field_0x25a8[i].field_0x0[0].x = i_this->field_0x3928[1].x + (dVar16 * i);
i_this->field_0x25a8[i].field_0x0[0].y = i_this->field_0x3928[1].y + (dVar15 * i);
i_this->field_0x25a8[i].field_0x0[0].z = i_this->field_0x3928[1].z + (dVar14 * i);
cMtx_YrotS(*calc_mtx, local_134.y);
f32 temp = cM_fsin(i * 0.2617994f);
local_e4.y = temp * -10.0f;
local_e4.z = temp * -20.0f;
MtxPosition(&local_e4, &cStack_f0);
i_this->field_0x25a8[i].field_0x0[0] += cStack_f0;
i_this->field_0x25a8[i].field_0x0138 = local_134.x;
i_this->field_0x25a8[i].field_0x013a = local_134.y + (i + -6) * 0x5dc;
for (int j = 1; j < 13; j++) {
i_this->field_0x25a8[i].field_0x0[j].x += local_108.x;
i_this->field_0x25a8[i].field_0x0[j].z += local_108.z;
}
joint_control(i_this, mantJS, i, uVar15, uVar14);
}
}
static void mant_move(mant_class* i_this) {
#if TARGET_PC
u8 uVar1 = i_this->field_0x0570.field_0x74 ^ 1;
cXyz* pcVar5 = &i_this->field_0x0570.mPos[uVar1][0];
#else
u8 uVar1 = i_this->field_0x0570.field_0x74;
cXyz* pcVar5 = i_this->field_0x0570.getPos();
#endif
mant_v_calc(i_this);
for (int i = 0; i < 13; i++) {
for (int j = 0; j < 13; j++) {
pcVar5[i + j * 13] = i_this->field_0x25a8[i].field_0x0[12 - j];
}
}
#if TARGET_PC
mant_build_anchor_frame(i_this->field_0x3928[0], i_this->field_0x3928[1], uVar1 == 0 ? i_this->field_0x0570.mMtx : i_this->field_0x0570.mMtx2);
i_this->field_0x0570.field_0x74 = uVar1;
#else
DCStoreRangeNoSync(i_this->field_0x0570.getPos(), 0x7ec);
#endif
}
static int mant_cut_type;
static int daMant_Execute(mant_class* i_this) {
f32 var_f31, var_f30;
int iVar8;
s16 unaff_r29;
int iVar2, uVar1, uVar4;
fopAc_ac_c* mant_actor = (fopAc_ac_c*)i_this;
fopAc_ac_c* unusedPlayerActor = dComIfGp_getPlayer(0);
daPy_py_c* unusedPlayer = (daPy_py_c*)unusedPlayerActor;
i_this->field_0x25a0++;
lbl_277_bss_0++;
if (i_this->field_0x399e != 0) {
i_this->field_0x399e--;
}
b_gnd_class* gndActor = (b_gnd_class*)fopAcM_SearchByID(mant_actor->parentActorID);
if (gndActor && gndActor->mDrawHorse != 0) {
i_this->field_0x394c = 21.0f;
i_this->field_0x3950 = 0.75f;
i_this->field_0x3958 = -5.0f;
i_this->field_0x3954 = -3.0f;
} else {
i_this->field_0x394c = 25.0f;
i_this->field_0x3950 = 0.55f + i_this->field_0x395c * 0.2f;
i_this->field_0x3958 = -20.0f + i_this->field_0x395c * 25.0f;
i_this->field_0x3954 = -13.0f - i_this->field_0x395c * 5.0f;
cLib_addCalc0(&i_this->field_0x395c, 1.0f, 0.05f);
cLib_addCalc0(&i_this->field_0x3960, 1.0f, 0.3f);
}
if (i_this->field_0x3965 != 0) {
i_this->field_0x3954 = 0.0f;
i_this->field_0x3958 = -10.0f;
}
mant_move(i_this);
i_this->field_0x3965 = 0;
i_this->field_0x3966 = 0;
i_this->field_0x3940 = mant_actor->current.pos;
iVar8 = 0;
if (i_this->field_0x3967 != 0) {
mant_cut_type = i_this->field_0x3967;
if (i_this->field_0x3968 < 15) {
i_this->field_0x3968++;
if (mant_cut_type == 0) {
iVar8 = 40;
} else if (mant_cut_type == 1) {
iVar8 = 30;
} else {
iVar8 = 20;
}
unaff_r29 = cM_rndF(65536.0f);
var_f31 = cM_rndFX(32.0f);
var_f30 = cM_rndFX(32.0f);
}
i_this->field_0x3967 = 0;
}
for (int i = 0; i < iVar8; i++) {
var_f31 += cM_ssin(unaff_r29);
var_f30 += -cM_scos(unaff_r29);
uVar4 = (int)(var_f31 + 64.0f) | (int)(var_f30 + 64.0f) << 7;
if (mant_cut_type == 0) {
if (i <= 3 || 36 <= i) {
iVar2 = 1;
} else if (i >= 12 && 28 >= i) {
iVar2 = 9;
} else {
iVar2 = 4;
}
} else if (mant_cut_type == 1) {
if (i <= 3 || 26 <= i) {
iVar2 = 1;
} else if (i >= 12 && 18 >= i) {
iVar2 = 9;
} else {
iVar2 = 4;
}
} else if (i <= 3 || 16 <= i) {
iVar2 = 1;
} else {
iVar2 = 4;
}
for (int j = 0; j < iVar2; j++) {
if (j == 0) {
uVar1 = uVar4;
} else if (j == 1) {
uVar1 = uVar4 + 1;
} else if (j == 2) {
uVar1 = uVar4 + 0x80;
} else if (j == 3) {
uVar1 = uVar4 + 0x81;
} else if (j == 3) {
uVar1 = uVar4 + 0x81;
} else if (j == 4) {
uVar1 = uVar4 + 2;
} else if (j == 5) {
uVar1 = uVar4 + 0x82;
} else if (j == 6) {
uVar1 = uVar4 + 0x102;
} else if (j == 7) {
uVar1 = uVar4 + 0x101;
} else if (j == 8) {
uVar1 = uVar4 + 0x100;
}
if (0 <= uVar1 && uVar1 < 0x4000) {
int iVar5 = (uVar1 & 7) + (uVar1 & 0x78) * 4 + (uVar1 >> 4 & 0x18) + (uVar1 & 0x3e00);
DUSK_IF_ELSE(l_Egnd_mantTEX_copy[iVar5], l_Egnd_mantTEX[iVar5]) = l_Egnd_mantTEX_U[iVar5] = 0;
}
#if TARGET_PC
if(textureObjsInitialized) {
GXInitTlutObjData(&tlutObj, l_Egnd_mantPAL); // make sure the cached textures are updated
}
#endif
}
}
return 1;
}
static BOOL daMant_IsDelete(mant_class* i_this) {
return TRUE;
}
static int daMant_Delete(mant_class* i_this) {
fopAcM_RegisterDeleteID(i_this, "Mant");
return 1;
}
static int daMant_Create(fopAc_ac_c* i_this) {
mant_class* m_this = (mant_class*)i_this;
fopAcM_RegisterCreateID(m_this, "Mant");
fopAcM_ct(m_this, mant_class);
//m_this->field_0x0570.field_0x74 = 0;
m_this->field_0x259c = fopAcM_GetParam(i_this);
fopAcM_SetMin(i_this, -2000.0f, -2000.0f, -2000.0f);
fopAcM_SetMax(i_this, 2000.0f, 2000.0f, 2000.0f);
m_this->field_0x0570.mArg0 = m_this->field_0x259c;
m_this->field_0x394c = 30.0f;
m_this->field_0x3950 = 7.0f / 10.0f;
m_this->field_0x3958 = -10.0f;
m_this->scale.set(1.0f, 1.0f, 1.0f);
for (int i = 0; i < 0x4000; i++) {
l_Egnd_mantTEX_U[i] = 6;
}
#if TARGET_PC
memcpy(l_Egnd_mantTEX_copy, l_Egnd_mantTEX, sizeof(l_Egnd_mantTEX_copy));
if(textureObjsInitialized) {
GXInitTlutObjData(&tlutObj, l_Egnd_mantPAL); // make sure the cached textures are updated
}
#endif
lbl_277_bss_0 = 0;
daMant_Execute(m_this);
return 4;
}
mant_j_s::~mant_j_s() {}
mant_j_s::mant_j_s() {}
daMant_packet_c::~daMant_packet_c() {}
// cXyz::cXyz() {
extern "C" void __ct__4cXyzFv() {
/* empty function */
}
static DUSK_CONST actor_method_class l_daMant_Method = {
(process_method_func)daMant_Create,
(process_method_func)daMant_Delete,
(process_method_func)daMant_Execute,
(process_method_func)daMant_IsDelete,
(process_method_func)daMant_Draw,
};
DUSK_PROFILE actor_process_profile_definition DUSK_CONST g_profile_MANT = {
/* Layer ID */ fpcLy_CURRENT_e,
/* List ID */ 8,
/* List Prio */ fpcPi_CURRENT_e,
/* Proc Name */ fpcNm_MANT_e,
/* Proc SubMtd */ &g_fpcLf_Method.base,
/* Size */ sizeof(mant_class),
/* Size Other */ 0,
/* Parameters */ 0,
/* Leaf SubMtd */ &g_fopAc_Method.base,
/* Draw Prio */ fpcDwPi_MANT_e,
/* Actor SubMtd */ &l_daMant_Method,
/* Status */ fopAcStts_UNK_0x40000_e | fopAcStts_UNK_0x4000_e,
/* Group */ fopAc_ACTOR_e,
/* Cull Type */ fopAc_CULLBOX_CUSTOM_e,
};