En_Ru: OK (Unused OoT Ruto) (#1035)

* Ruto: OK

* Ruto: better walking water sfx function name and less fake match

* Ruto: formater pls

* Ruto: Requested changes, better display list documentation

* Ruto: requested changes

* Ruto: formater pass

* Ruto: casts were removeable

* Apply suggestions from code review

Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>

* Update src/overlays/actors/ovl_En_Ru/z_en_ru.c

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* Ruto: array size fix

* Ruto: data shuffle solved

* Ruto: requested name changes

* Ru: requested changes

* Ru: count instead of size

Co-authored-by: Isghj8 <isghj8@gmail.com>
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
This commit is contained in:
Isghj
2022-09-29 17:29:25 -07:00
committed by GitHub
parent 8f2fe9b3c7
commit 7ed0d14bfe
5 changed files with 400 additions and 112 deletions
+271 -27
View File
@@ -15,9 +15,8 @@ void EnRu_Destroy(Actor* thisx, PlayState* play);
void EnRu_Update(Actor* thisx, PlayState* play);
void EnRu_Draw(Actor* thisx, PlayState* play);
void func_80A38DF4(EnRu* this, PlayState* play);
void EnRu_DoNothing(EnRu* this, PlayState* play);
#if 0
const ActorInit En_Ru_InitVars = {
ACTOR_EN_RU,
ACTORCAT_NPC,
@@ -30,18 +29,29 @@ const ActorInit En_Ru_InitVars = {
(ActorFunc)EnRu_Draw,
};
// static ColliderCylinderInit sCylinderInit = {
static ColliderCylinderInit D_80A39450 = {
{ COLTYPE_HIT0, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
{ ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_HIT0,
AT_NONE,
AC_ON | AC_TYPE_PLAYER,
OC1_ON | OC1_TYPE_ALL,
OC2_TYPE_1,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK1,
{ 0x00000000, 0x00, 0x00 },
{ 0xF7CFFFFF, 0x00, 0x00 },
TOUCH_NONE | TOUCH_SFX_NORMAL,
BUMP_ON,
OCELEM_ON,
},
{ 18, 64, 0, { 0, 0, 0 } },
};
// sColChkInfoInit
static CollisionCheckInfoInit2 D_80A3947C = { 0, 0, 0, 0, MASS_IMMOVABLE };
static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE };
// static DamageTable sDamageTable = {
static DamageTable D_80A39488 = {
static DamageTable sDamageTable = {
/* Deku Nut */ DMG_ENTRY(0, 0x0),
/* Deku Stick */ DMG_ENTRY(0, 0x0),
/* Horse trample */ DMG_ENTRY(0, 0x0),
@@ -76,34 +86,268 @@ static DamageTable D_80A39488 = {
/* Powder Keg */ DMG_ENTRY(0, 0x0),
};
#endif
static AnimationInfoS sAnimationInfo[] = {
{ &gAdultRutoIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &gAdultRutoIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &gAdultRutoRaisingArmsUpAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &gAdultRutoCrossingArmsAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &gAdultRutoLookingDownLeftAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &gAdultRutoIdleHandsOnHipsAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &gAdultRutoHeadTurnDownLeftAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
{ &gAdultRutoSwimmingUpAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 },
};
extern ColliderCylinderInit D_80A39450;
extern CollisionCheckInfoInit2 D_80A3947C;
extern DamageTable D_80A39488;
// in PostLimbdraw, converts limbIndex to bodyPartsPos index
static s8 sBodyPartPosIndices[] = {
-1, -1, 12, 13, 14, -1, 9, 10, 11, -1, 0, 6, -1, -1, 7, 8, 2, -1, -1, 3, 4, 2, 1,
};
extern UNK_TYPE D_0600C700;
static s8 sRuBodyParts[RU_BODYPARTSPOS_COUNT] = {
0, 0, 0, 0, 3, 4, 0, 6, 7, 0, 9, 10, 0, 12, 13,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/func_80A389A0.s")
static u8 sRuShadowSizes[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/func_80A38A68.s")
static TrackOptionsSet sTrackOptions = {
{ 0xFA0, 4, 1, 3 }, { 0x1770, 4, 1, 6 }, { 0xFA0, 4, 1, 3 }, { 0x1770, 4, 1, 6 }
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/func_80A38B7C.s")
s32 EnRu_ChangeAnim(SkelAnime* skelAnime, s16 animIndex) {
s16 lastFrame;
s32 ret = false;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/func_80A38BF0.s")
if ((animIndex >= 0) && (animIndex < ARRAY_COUNT(sAnimationInfo))) {
lastFrame = sAnimationInfo[animIndex].frameCount;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/func_80A38C70.s")
ret = true;
if (lastFrame < 0) {
lastFrame = Animation_GetLastFrame(sAnimationInfo[animIndex].animation);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/func_80A38DF4.s")
Animation_Change(skelAnime, sAnimationInfo[animIndex].animation, sAnimationInfo[animIndex].playSpeed,
sAnimationInfo[animIndex].startFrame, lastFrame, sAnimationInfo[animIndex].mode,
sAnimationInfo[animIndex].morphFrames);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/EnRu_Init.s")
return ret;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/EnRu_Destroy.s")
// En_Zo has a copy of this function
s32 EnRu_PlayWalkingSound(EnRu* this, PlayState* play) {
u8 leftWasGrounded;
u8 rightWasGrounded;
s32 waterSfxId;
s16 sfxId;
u8 isFootGrounded;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/EnRu_Update.s")
leftWasGrounded = this->isLeftFootGrounded;
rightWasGrounded = this->isRightFootGrounded;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/func_80A38FB4.s")
if (this->actor.bgCheckFlags & 0x20) {
if (this->actor.depthInWater < 20.0f) {
waterSfxId = NA_SE_PL_WALK_WATER0 - SFX_FLAG;
} else {
waterSfxId = NA_SE_PL_WALK_WATER1 - SFX_FLAG;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/func_80A390F8.s")
sfxId = waterSfxId + SFX_FLAG;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ru/EnRu_Draw.s")
} else {
sfxId = SurfaceType_GetSfx(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId) + SFX_FLAG;
}
this->isLeftFootGrounded = isFootGrounded = SubS_IsFloorAbove(play, &this->leftFootPos, -6.0f);
if (this->isLeftFootGrounded && !leftWasGrounded && isFootGrounded) {
Actor_PlaySfxAtPos(&this->actor, sfxId);
}
this->isRightFootGrounded = isFootGrounded = SubS_IsFloorAbove(play, &this->rightFootPos, -6.0f);
if (this->isRightFootGrounded && !rightWasGrounded && isFootGrounded) {
Actor_PlaySfxAtPos(&this->actor, sfxId);
}
return false;
}
// This function is only ever called with eyeStateMax == 3
void EnRu_UpdateEyes(EnRu* this, s32 eyeStateMax) {
if (DECR(this->blinkTimer) == 0) {
this->eyeState++;
if (this->eyeState >= eyeStateMax) {
this->eyeState = 0;
this->blinkTimer = Rand_S16Offset(30, 30);
}
}
}
void EnRu_UpdateCollider(EnRu* this, PlayState* play) {
this->collider.dim.pos.x = this->actor.world.pos.x;
this->collider.dim.pos.y = this->actor.world.pos.y;
this->collider.dim.pos.z = this->actor.world.pos.z;
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
}
void EnRu_UpdateModel(EnRu* this, PlayState* play) {
Player* player = GET_PLAYER(play);
SkelAnime_Update(&this->skelAnime);
// Head and Torso tracking to Player if in front of Ru.
if (SubS_AngleDiffLessEqual(this->actor.shape.rot.y, 0x2710, this->actor.yawTowardsPlayer)) {
Vec3f playerPos;
playerPos.x = player->actor.world.pos.x;
playerPos.y = player->bodyPartsPos[7].y + 3.0f;
playerPos.z = player->actor.world.pos.z;
SubS_TrackPoint(&playerPos, &this->actor.focus.pos, &this->actor.shape.rot, &this->trackTarget, &this->headRot,
&this->torsoRot, &sTrackOptions);
} else { // smooth her back to facing forward
Math_SmoothStepToS(&this->trackTarget.x, 0, 4, 0x3E8, 1);
Math_SmoothStepToS(&this->trackTarget.y, 0, 4, 0x3E8, 1);
Math_SmoothStepToS(&this->headRot.x, 0, 4, 0x3E8, 1);
Math_SmoothStepToS(&this->headRot.y, 0, 4, 0x3E8, 1);
Math_SmoothStepToS(&this->torsoRot.x, 0, 4, 0x3E8, 1);
Math_SmoothStepToS(&this->torsoRot.y, 0, 4, 0x3E8, 1);
}
EnRu_UpdateEyes(this, 3);
EnRu_PlayWalkingSound(this, play);
SubS_FillLimbRotTables(play, this->limbRotTableY, this->limbRotTableZ, RU2_LIMB_MAX);
}
void EnRu_DoNothing(EnRu* this, PlayState* play) {
}
void EnRu_Init(Actor* thisx, PlayState* play) {
s32 pad;
EnRu* this = THIS;
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
SkelAnime_InitFlex(play, &this->skelAnime, &gAdultRutoSkel, NULL, this->jointTable, this->morphTable, RU2_LIMB_MAX);
EnRu_ChangeAnim(&this->skelAnime, 0);
Collider_InitCylinder(play, &this->collider);
Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
this->path = SubS_GetPathByIndex(play, RU_GET_PATH(thisx), 0x3F);
Actor_SetScale(&this->actor, 0.01f);
this->actionFunc = EnRu_DoNothing;
this->actor.gravity = -4.0f;
}
void EnRu_Destroy(Actor* thisx, PlayState* play) {
EnRu* this = THIS;
Collider_DestroyCylinder(play, &this->collider);
}
void EnRu_Update(Actor* thisx, PlayState* play) {
EnRu* this = THIS;
this->actionFunc(this, play);
Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4);
EnRu_UpdateModel(this, play);
EnRu_UpdateCollider(this, play);
}
s32 EnRu_OverrideLimbdraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx,
Gfx** gfx) {
EnRu* this = THIS;
if (limbIndex == RU2_LIMB_HEAD) {
Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY);
Matrix_RotateXS(this->headRot.y, MTXMODE_APPLY);
Matrix_RotateZS(this->headRot.x, MTXMODE_APPLY);
Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY);
}
if (limbIndex == RU2_LIMB_TORSO) {
Matrix_RotateYS(this->torsoRot.y, MTXMODE_APPLY);
Matrix_RotateXS(this->torsoRot.x, MTXMODE_APPLY);
}
if ((limbIndex == RU2_LIMB_TORSO) || (limbIndex == RU2_LIMB_LEFT_UPPER_ARM) ||
(limbIndex == RU2_LIMB_RIGHT_UPPER_ARM)) {
rot->y += (s16)(Math_SinS(this->limbRotTableY[limbIndex]) * 200.0f);
rot->z += (s16)(Math_CosS(this->limbRotTableZ[limbIndex]) * 200.0f);
}
return false;
}
void EnRu_PostLimbdraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) {
EnRu* this = THIS;
Vec3f headFocus = { 800.0f, 0, 0 };
Vec3f bodyPartPos = { 0, 0, 0 };
if (sBodyPartPosIndices[limbIndex] >= 0) {
Matrix_MultVec3f(&bodyPartPos, &this->bodyPartsPos[sBodyPartPosIndices[limbIndex]]);
}
if (limbIndex == RU2_LIMB_HEAD) {
Matrix_MultVec3f(&headFocus, &thisx->focus.pos);
}
if (limbIndex == RU2_LIMB_LEFT_FOOT) {
Matrix_MultVec3f(&bodyPartPos, &this->leftFootPos);
}
if (limbIndex == RU2_LIMB_RIGHT_FOOT) {
Matrix_MultVec3f(&bodyPartPos, &this->rightFootPos);
}
}
// This is a copy of displaylist found in En_Zo
static Gfx sTransparencyDlist[] = {
gsDPSetRenderMode(AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL |
G_RM_FOG_SHADE_A,
AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL |
GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)),
gsDPSetAlphaCompare(G_AC_THRESHOLD),
gsSPEndDisplayList(),
};
void EnRu_Draw(Actor* thisx, PlayState* play) {
EnRu* this = THIS;
u8* shadowTex = GRAPH_ALLOC(play->state.gfxCtx, SUBS_SHADOW_TEX_SIZE);
u8* shadowTexIter;
s32 i;
TexturePtr eyeTextures[] = { gAdultRutoEyeOpenTex, gAdultRutoEyeHalfTex, gAdultRutoEyeClosedTex };
OPEN_DISPS(play->state.gfxCtx);
func_8012C28C(play->state.gfxCtx);
gDPPipeSync(POLY_OPA_DISP++);
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
gDPPipeSync(POLY_OPA_DISP++);
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(eyeTextures[this->eyeState]));
// only runs the last command of the display list, which is gsSPEndDisplayList
gSPSegment(POLY_OPA_DISP++, 0x0C, &sTransparencyDlist[2]);
POLY_OPA_DISP =
SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnRu_OverrideLimbdraw, EnRu_PostLimbdraw, &this->actor, POLY_OPA_DISP);
Matrix_RotateXS(0, MTXMODE_NEW);
for (i = 0, shadowTexIter = shadowTex; i < SUBS_SHADOW_TEX_SIZE; i++) {
*shadowTexIter++ = 0;
}
for (i = 0; i < 5; i++) {
SubS_GenShadowTex(&this->bodyPartsPos[0], &this->actor.world.pos, shadowTex, (i / 5.0f),
(ARRAY_COUNT(sRuBodyParts)), sRuShadowSizes, sRuBodyParts);
}
SubS_DrawShadowTex(&this->actor, &play->state, shadowTex);
CLOSE_DISPS(play->state.gfxCtx);
}
+26 -1
View File
@@ -2,15 +2,40 @@
#define Z_EN_RU_H
#include "global.h"
#include "objects/object_ru2/object_ru2.h"
#define RU_GET_PATH(thisx) ((thisx->params & 0x7E00) >> 9)
struct EnRu;
typedef void (*EnRuActionFunc)(struct EnRu*, PlayState*);
#define RU_BODYPARTSPOS_COUNT 15
typedef struct EnRu {
/* 0x000 */ Actor actor;
/* 0x144 */ EnRuActionFunc actionFunc;
/* 0x148 */ char unk_148[0x30C];
/* 0x148 */ SkelAnime skelAnime;
/* 0x18C */ ColliderCylinder collider;
/* 0x1D8 */ UNK_TYPE1 pad1D8[0x4];
/* 0x1DC */ Path* path; // path is prepared in EnRu_Init, but unused after
/* 0x1E0 */ UNK_TYPE1 pad1E0[0x4];
/* 0x1E4 */ Vec3f leftFootPos;
/* 0x1F0 */ Vec3f rightFootPos;
/* 0x1FC */ u8 isLeftFootGrounded;
/* 0x1FD */ u8 isRightFootGrounded;
/* 0x1FE */ Vec3s jointTable[RU2_LIMB_MAX];
/* 0x288 */ Vec3s morphTable[RU2_LIMB_MAX];
/* 0x312 */ Vec3s trackTarget;
/* 0x318 */ Vec3s headRot;
/* 0x31E */ Vec3s torsoRot;
/* 0x324 */ UNK_TYPE1 pad324[0x12];
/* 0x336 */ s16 limbRotTableY[RU2_LIMB_MAX];
/* 0x364 */ s16 limbRotTableZ[RU2_LIMB_MAX];
/* 0x394 */ Vec3f bodyPartsPos[RU_BODYPARTSPOS_COUNT];
/* 0x348 */ UNK_TYPE1 padUNK[6];
/* 0x44E */ s16 eyeState;
/* 0x450 */ s16 blinkTimer;
} EnRu; // size = 0x454
extern const ActorInit En_Ru_InitVars;