summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrakxo <87568477+Prakxo@users.noreply.github.com>2024-02-09 17:55:22 +0100
committerGitHub <noreply@github.com>2024-02-09 09:55:22 -0700
commit4a679da4895cf66b68dd90a601a4c0c9e41e5409 (patch)
tree65dba5a6079692096fdd9dd78ac0793e7a42f38f
parentbebacf3ba88c75c66f60ffc6f48371430607338e (diff)
m_actor_shadow OK (#142)
* werk * more werk * m_actor_shadow OK * format * protos fix * jenkins happy
-rw-r--r--include/gfx.h4
-rw-r--r--include/m_actor.h16
-rw-r--r--include/m_actor_shadow.h73
-rw-r--r--include/m_collision_bg.h4
-rw-r--r--include/m_field_info.h1
-rw-r--r--include/m_kankyo.h6
-rw-r--r--include/m_rcp.h2
-rw-r--r--include/sys_math3d.h6
-rw-r--r--linker_scripts/jp/symbol_addrs_code.txt2
-rw-r--r--linker_scripts/jp/undefined_syms.ld4
-rw-r--r--src/code/game.c6
-rw-r--r--src/code/m_actor.c20
-rw-r--r--src/code/m_actor_shadow.c414
-rw-r--r--src/overlays/gamestates/ovl_play/m_play.c6
-rw-r--r--yamls/jp/code.yaml6
15 files changed, 503 insertions, 67 deletions
diff --git a/include/gfx.h b/include/gfx.h
index 3ab54a0..485c543 100644
--- a/include/gfx.h
+++ b/include/gfx.h
@@ -20,7 +20,7 @@ typedef struct GraphicsContext {
/* 0x290 */ TwoHeadGfxArena polyOpa;
/* 0x2A0 */ TwoHeadGfxArena polyXlu;
/* 0x2B0 */ TwoHeadGfxArena unk_2B0;
- /* 0x2C0 */ TwoHeadGfxArena unk_2C0;
+ /* 0x2C0 */ TwoHeadGfxArena shadow;
/* 0x2D0 */ TwoHeadGfxArena light;
/* 0x2E0 */ UNK_TYPE1 unk_2E0[0x4];
/* 0x2E4 */ UNK_PTR unk_2E4;
@@ -40,7 +40,7 @@ typedef struct GraphicsContext {
#define POLY_OPA_DISP __gfxCtx->polyOpa.p
#define POLY_XLU_DISP __gfxCtx->polyXlu.p
#define UNK_2B0_DISP __gfxCtx->unk_2B0.p
-#define UNK_2C0_DISP __gfxCtx->unk_2C0.p
+#define SHADOW_DISP __gfxCtx->shadow.p
#define LIGHT_DISP __gfxCtx->light.p
// __gfxCtx shouldn't be used directly.
diff --git a/include/m_actor.h b/include/m_actor.h
index 1c08512..808b592 100644
--- a/include/m_actor.h
+++ b/include/m_actor.h
@@ -76,16 +76,16 @@ typedef struct Shape_Info {
/* 0x00 */ s_xyz rot;
/* 0x08 */ f32 unk_08;
/* 0x0C */ Shape_Info_unk_0C unk_0C;
- /* 0x10 */ f32 unk_10;
- /* 0x14 */ f32 unk_14;
- /* 0x18 */ f32 unk_18;
- /* 0x1C */ f32 unk_1C;
- /* 0x20 */ s32 unk_20;
- /* 0x24 */ xyz_t* unk_24; // maybe PosRot*
+ /* 0x10 */ f32 shadowSizeX;
+ /* 0x14 */ f32 shadowSizeZ;
+ /* 0x18 */ f32 shadowSizeRate;
+ /* 0x1C */ f32 shadowAlphaRate;
+ /* 0x20 */ u32 unk_20;
+ /* 0x24 */ xyz_t* shadowPosition; // maybe PosRot*
/* 0x28 */ s32 unk_28;
- /* 0x2C */ s8 unk_2C;
+ /* 0x2C */ u8 drawShadow;
/* 0x2D */ s8 unk_2D;
- /* 0x2E */ s8 unk_2E;
+ /* 0x2E */ u8 forceShadow;
/* 0x2F */ UNK_TYPE1 unk_2F[0x1];
/* 0x30 */ xyz_t feetPos[FOOT_MAX];
} Shape_Info; // size = 0x48
diff --git a/include/m_actor_shadow.h b/include/m_actor_shadow.h
index 14eac8d..2b81471 100644
--- a/include/m_actor_shadow.h
+++ b/include/m_actor_shadow.h
@@ -2,33 +2,52 @@
#define M_ACTOR_SHADOW_H
#include "ultra64.h"
+#include "m_lib.h"
+
+typedef struct ShadowInfo{
+ /* 0x00 */ xyz_t position;
+ /* 0x0C */ f32 groundY;
+ /* 0x10 */ f32 unk10;
+ /* 0x14 */ f32 unk14;
+ /* 0x18 */ f32 unk18;
+ /* 0x1C */ f32 unk1C;
+ /* 0x20 */ s16 unk20;
+ /* 0x22 */ s16 unk22;
+ /* 0x24 */ s16 unk24;
+ /* 0x26 */ s16 unk26;
+ /* 0x28 */ char pad28[0xC];
+ /* 0x34 */ s32 unk34;
+ /* 0x38 */ s32 kind;
+}ShadowInfo;
+
+
+s32 mActorShadow_OperateScrollLimit(s32 value, s32 step, s32 limit);
+Gfx* mActorShadow_TileScroll2(u32* x1, u32* y1, s32 step1, s32 step2, s32 limit1, s32 limit2, s32 width1, s32 height1, u32* x2, u32* y2, s32 step3, s32 step4, s32 limit3, s32 limit4, s32 width2, s32 height2, Game* game);
+void mActorShadow_AdjustRate(f32* rate);
+void mActorShadow_GetTimeAngleY_TimeAlpha(ShadowInfo* shadow, Game_Play* play);
+void mActorShadow_GetGroundAverageAngle(ShadowInfo* shadow);
+void mActorShadow_GetDistanceRate(ShadowInfo* shadow, f32 rate);
+f32 mActorShadow_GetAbsBigger(f32 a, f32 b);
+void mActorShadow_RadiusScaleRate(Actor* actor, ShadowInfo* shadow);
+void mActorShadow_GetShadowTopPos_GetSlideS(ShadowInfo* shadow);
+Gfx* mActorShadow_SetTexScroll(Actor* actor, ShadowInfo* shadow, Game* game);
+void mActorShadow_GetLastAlphaScale(f32* scale, u8* alpha, Actor* actor, ShadowInfo* shadow);
+void mActorShadow_DrawActorShadow(Actor* actor, ShadowInfo* shadow, Game* game, f32 rad, s32 id, xyz_t ofs);
+void mActorShadow_GetShadowPosition(Actor* actor, xyz_t* position);
+s32 mActorShadow_GetShadowKind(void);
+f32 mAc_GetShadowGroundY_NoneForce(ShadowInfo* shadow);
+f32 mAc_GetShadowGroundY_Force(ShadowInfo* shadow);
+void mAc_DecideShadowRadius_IamNotFish(ShadowInfo* shadow, Actor* actor, f32* radius);
+void mAc_DecideShadowRadius_IamFish(ShadowInfo* shadow, Actor* actor, f32* radius);
+void mAc_ActorShadowDraw_ShadowDrawFlagOff(Actor* actor, Game_Play* play, s32 arg2, xyz_t arg3, f32 arg6);
+void mAc_ActorShadowDraw_ShadowDrawFlagOn(Actor* actor, Game_Play* play, s32 proc, xyz_t pos, f32 rate);
+void mAc_ActorShadowDraw(Actor* actor, Game_Play* play, s32 arg2, xyz_t arg3, f32 arg6);
+void mActorShadow_SetForceShadowPos(Actor* actor, xyz_t* pos);
+void mActorShadow_UnSetForceShadowPos(Actor* actor);
+void mAc_NormalActorShadow(Actor* actor, Game_Play* play, f32 rad);
+void mAc_UnagiActorShadow(Actor* actor, Game_Play* play, xyz_t pos);
+void mAc_ActorShadowCircle(Actor* actor, LightsN* lights, Game_Play* play);
+void mAc_ActorShadowEllipse(Actor* actor, LightsN* lights, Game_Play* play);
-// void mActorShadow_OperateScrollLimit();
-// void mActorShadow_TileScroll2();
-// void mActorShadow_AdjustRate();
-// void mActorShadow_GetTimeAngleY_TimeAlpha();
-// void mActorShadow_GetGroundAverageAngle();
-// void mActorShadow_GetDistanceRate();
-// void mActorShadow_GetAbsBigger();
-// void mActorShadow_RadiusScaleRate();
-// void mActorShadow_GetShadowTopPos_GetSlideS();
-// void mActorShadow_SetTexScroll();
-// void mActorShadow_GetLastAlphaScale();
-// void mActorShadow_DrawActorShadow();
-// void mActorShadow_GetShadowPosition();
-// void mActorShadow_GetShadowKind();
-// void mAc_GetShadowGroundY_NoneForce();
-// void mAc_GetShadowGroundY_Force();
-// void mAc_DecideShadowRadius_IamNotFish();
-// void mAc_DecideShadowRadius_IamFish();
-// void mAc_ActorShadowDraw_ShadowDrawFlagOff();
-// void mAc_ActorShadowDraw_ShadowDrawFlagOn();
-// void mAc_ActorShadowDraw();
-// void mActorShadow_SetForceShadowPos();
-// void mActorShadow_UnSetForceShadowPos();
-// void mAc_NormalActorShadow();
-// void mAc_UnagiActorShadow();
-// void mAc_ActorShadowCircle();
-// void mAc_ActorShadowEllipse();
#endif
diff --git a/include/m_collision_bg.h b/include/m_collision_bg.h
index a55f16f..b231c38 100644
--- a/include/m_collision_bg.h
+++ b/include/m_collision_bg.h
@@ -193,12 +193,12 @@ void func_8006C8D0_jp(void);
// void func_80071064_jp();
// void func_800713CC_jp();
// void func_80071460_jp();
-// void mCoBG_GetShadowBgY_AngleS_FromWpos();
+f32 mCoBG_GetShadowBgY_AngleS_FromWpos(s_xyz*, xyz_t,f32);
// void func_800715B4_jp();
// void func_80071604_jp();
// void func_80071728_jp();
// void func_8007175C_jp();
-// void func_80071884_jp();
+f32 mCoBG_GetBgY_AngleS_FromWpos(s_xyz* angleToGround, xyz_t wpos, f32 offsetY);
// void func_80071A08_jp();
// void func_80071AB8_jp();
f32 mCoBG_GetBgY_OnlyCenter_FromWpos2(xyz_t arg0, f32 arg1);
diff --git a/include/m_field_info.h b/include/m_field_info.h
index b9a6f13..6dd33d5 100644
--- a/include/m_field_info.h
+++ b/include/m_field_info.h
@@ -23,6 +23,7 @@ typedef enum FieldType {
#define FI_TO_FIELD_ID(type, index) (((type) << 12) | (index))
+#define FI_GET_TYPE(id) ((id) & 0xF000)
typedef enum FieldRoom {
/* 0x6000 */ FI_FIELD_PLAYER0_ROOM = FI_TO_FIELD_ID(FI_FIELDTYPE_PLAYER_ROOM, 0),
diff --git a/include/m_kankyo.h b/include/m_kankyo.h
index 5447f4f..8061f79 100644
--- a/include/m_kankyo.h
+++ b/include/m_kankyo.h
@@ -24,7 +24,9 @@ typedef struct Kankyo {
/* 0xAE */ u8 unk_AE;
/* 0xAF */ u8 unk_AF;
/* 0xB0 */ u8 unk_B0;
- /* 0xB1 */ UNK_TYPE1 unk_B1[0xF];
+ /* 0xB1 */ UNK_TYPE1 unk_B1[0xB];
+ /* 0xBC */ u8 shadowAlpha;
+ /* 0xBD */ UNK_TYPE1 unk_BD[0x2];
/* 0xC0 */ Kankyo_unk_C0 unk_C0;
/* 0xC4 */ UNK_TYPE1 unk_C4[0x4];
} Kankyo; // size = 0xC8
@@ -78,7 +80,7 @@ void mEnv_DecideWeather_NormalGameStart(void);
// void func_8009949C_jp();
// void func_80099594_jp();
// void func_800996CC_jp();
-// void mEnv_GetShadowPrimColor_Light();
+void mEnv_GetShadowPrimColor_Light(u8*,u8*,u8*, struct Game*);
// void func_80099718_jp();
// void func_80099728_jp();
// void mEnv_MakeWindowLightAlpha();
diff --git a/include/m_rcp.h b/include/m_rcp.h
index e4a33d3..93dd903 100644
--- a/include/m_rcp.h
+++ b/include/m_rcp.h
@@ -15,7 +15,7 @@ Gfx* gfx_set_fog_nosync(Gfx* gfx, u8 arg1, u8 arg2, u8 arg3, s32 arg4, s16 arg5,
// void func_800BD498_jp();
// void func_800BD4C0_jp();
void _texture_z_light_fog_prim(struct GraphicsContext *gfxCtx);
-// void _texture_z_light_fog_prim_shadow();
+void _texture_z_light_fog_prim_shadow(struct GraphicsContext*);
// void func_800BD538_jp();
void _texture_z_light_fog_prim_xlu(struct GraphicsContext *gfxCtx);
void func_800BD5C0_jp(struct GraphicsContext* gfxCtx);
diff --git a/include/sys_math3d.h b/include/sys_math3d.h
index 525a89f..58e1405 100644
--- a/include/sys_math3d.h
+++ b/include/sys_math3d.h
@@ -111,9 +111,9 @@ s32 Math3D_pipeVsPipe_cl(Pipe* pipe1, Pipe* pipe2, f32* arg2);
// void func_800DFCA4_jp();
// void func_800DFD10_jp();
// void func_800DFD7C_jp();
-// void sMath_RotateY();
-// void sMath_RotateX();
-// void sMath_RotateZ();
+void sMath_RotateY(xyz_t* pos, f32 rad);
+void sMath_RotateX(xyz_t* pos, f32 rad);
+void sMath_RotateZ(xyz_t* pos, f32 rad);
extern xyz_t ZeroVec;
diff --git a/linker_scripts/jp/symbol_addrs_code.txt b/linker_scripts/jp/symbol_addrs_code.txt
index 7ef76c5..fc13d95 100644
--- a/linker_scripts/jp/symbol_addrs_code.txt
+++ b/linker_scripts/jp/symbol_addrs_code.txt
@@ -767,7 +767,7 @@ func_800715B4_jp = 0x800715B4; // type:func
func_80071604_jp = 0x80071604; // type:func
func_80071728_jp = 0x80071728; // type:func
func_8007175C_jp = 0x8007175C; // type:func
-func_80071884_jp = 0x80071884; // type:func
+mCoBG_GetBgY_AngleS_FromWpos = 0x80071884; // type:func
func_80071A08_jp = 0x80071A08; // type:func
func_80071AB8_jp = 0x80071AB8; // type:func
mCoBG_GetBgY_OnlyCenter_FromWpos2 = 0x80071B78; // type:func
diff --git a/linker_scripts/jp/undefined_syms.ld b/linker_scripts/jp/undefined_syms.ld
index 56554f9..95a1287 100644
--- a/linker_scripts/jp/undefined_syms.ld
+++ b/linker_scripts/jp/undefined_syms.ld
@@ -198,8 +198,8 @@ D_C000000 = 0x0C000000;
// m_actor_shadow
-D_4005540 = 0x04005540;
-D_4005710 = 0x04005710;
+ef_shadow_in_modelT = 0x04005540;
+ef_shadow_out_modelT = 0x04005710;
D_6000000 = 0x06000000;
D_6000008 = 0x06000008;
D_6001628 = 0x06001628;
diff --git a/src/code/game.c b/src/code/game.c
index 7767fc0..07fc3ca 100644
--- a/src/code/game.c
+++ b/src/code/game.c
@@ -145,9 +145,9 @@ void game_draw_first(GraphicsContext* gfxCtx) {
gSPSegment(UNK_2B0_DISP++, 0x0F, gfxCtx->unk_2E4);
gSPSegment(UNK_2B0_DISP++, 0x0E, temp_v0);
- gSPSegment(UNK_2C0_DISP++, 0x00, NULL);
- gSPSegment(UNK_2C0_DISP++, 0x0F, gfxCtx->unk_2E4);
- gSPSegment(UNK_2C0_DISP++, 0x0E, temp_v0);
+ gSPSegment(SHADOW_DISP++, 0x00, NULL);
+ gSPSegment(SHADOW_DISP++, 0x0F, gfxCtx->unk_2E4);
+ gSPSegment(SHADOW_DISP++, 0x0E, temp_v0);
gSPSegment(LIGHT_DISP++, 0x00, NULL);
gSPSegment(LIGHT_DISP++, 0x0F, gfxCtx->unk_2E4);
diff --git a/src/code/m_actor.c b/src/code/m_actor.c
index ea4ee9c..688230c 100644
--- a/src/code/m_actor.c
+++ b/src/code/m_actor.c
@@ -116,14 +116,14 @@ s32 Actor_data_bank_dma_end_check(Actor* actor, Game_Play* game_play) {
void Shape_Info_init(Actor* actor, f32 arg1, Shape_Info_unk_0C arg2, f32 arg3, f32 arg4) {
actor->shape.unk_08 = arg1;
actor->shape.unk_0C = arg2;
- actor->shape.unk_10 = arg3;
- actor->shape.unk_14 = arg4;
- actor->shape.unk_2C = 1;
+ actor->shape.shadowSizeX = arg3;
+ actor->shape.shadowSizeZ = arg4;
+ actor->shape.drawShadow = TRUE;
actor->shape.unk_20 = 0;
- actor->shape.unk_18 = 1.0f;
- actor->shape.unk_1C = 1.0f;
- actor->shape.unk_2E = 0;
- actor->shape.unk_24 = &actor->world.pos;
+ actor->shape.shadowSizeRate = 1.0f;
+ actor->shape.shadowAlphaRate = 1.0f;
+ actor->shape.forceShadow = FALSE;
+ actor->shape.shadowPosition = &actor->world.pos;
actor->shape.unk_28 = -1;
actor->shape.unk_2D = 0;
}
@@ -181,8 +181,8 @@ void Actor_ct(Actor* actor, Game_Play* game_play) {
actor->uncullZoneScale = 350.0f;
actor->uncullZoneDownward = 700.0f;
- actor->shape.unk_18 = 1.0f;
- actor->shape.unk_1C = 1.0f;
+ actor->shape.shadowSizeRate = 1.0f;
+ actor->shape.shadowAlphaRate = 1.0f;
actor->unk_13C = 1000.0f;
actor->unk_140 = 350.0f;
@@ -277,7 +277,7 @@ void Actor_draw(Game_Play* game_play, Actor* actor) {
gSPSegment(POLY_OPA_DISP++, 0x06, segment);
gSPSegment(POLY_XLU_DISP++, 0x06, segment);
- gSPSegment(UNK_2C0_DISP++, 0x06, segment);
+ gSPSegment(SHADOW_DISP++, 0x06, segment);
}
actor->draw(actor, game_play);
diff --git a/src/code/m_actor_shadow.c b/src/code/m_actor_shadow.c
new file mode 100644
index 0000000..c0ab1bd
--- /dev/null
+++ b/src/code/m_actor_shadow.c
@@ -0,0 +1,414 @@
+#include "m_actor_shadow.h"
+#include "m_rcp.h"
+#include "m_collision_obj.h"
+#include "macros.h"
+#include "sys_math3d.h"
+#include "m_field_info.h"
+
+extern Gfx ef_shadow_out_modelT[];
+extern Gfx ef_shadow_in_modelT[];
+
+s32 mActorShadow_OperateScrollLimit(s32 value, s32 step, s32 limit) {
+ if (step != 0) {
+ if (step > 0) {
+ value += step;
+ if (value > limit) {
+ value = limit;
+ }
+ } else if (step < 0) {
+ value += step;
+ if (value < limit) {
+ value = limit;
+ }
+ }
+ }
+ return value;
+}
+
+Gfx* mActorShadow_TileScroll2(u32* x1, u32* y1, s32 step1, s32 step2, s32 limit1, s32 limit2, s32 width1, s32 height1,
+ u32* x2, u32* y2, s32 step3, s32 step4, s32 limit3, s32 limit4, s32 width2, s32 height2,
+ Game* game) {
+ *x1 = mActorShadow_OperateScrollLimit(*x1, step1, limit1);
+ *y1 = mActorShadow_OperateScrollLimit(*y1, step2, limit2);
+ *x2 = mActorShadow_OperateScrollLimit(*x2, step3, limit3);
+ *y2 = mActorShadow_OperateScrollLimit(*y2, step4, limit4);
+
+ return two_tex_scroll(game->gfxCtx, 0, *x1, *y1, width1, height1, 1, *x2, *y2, width2, height2);
+}
+
+void mActorShadow_AdjustRate(f32* rate) {
+ if (*rate < 0.0f) {
+ *rate = 0.0f;
+ } else if (*rate > 1.0f) {
+ *rate = 1.0f;
+ }
+}
+
+void mActorShadow_GetTimeAngleY_TimeAlpha(ShadowInfo* shadow, Game_Play* play) {
+ f32 timef;
+ s32 timesec = common_data.time.nowSec;
+ f32 angle;
+ shadow->unk1C = play->kankyo.shadowAlpha;
+
+ // Between 4 a.m and 8 p.m
+ if ((timesec >= 14400) && (timesec < 72000)) {
+ UNUSED f32 scopedTemp;
+ timef = (timesec - 14400) / 57600.0f;
+ angle = 16384;
+ } // Between 12 a.m and 4 a.m
+ else if (timesec < 14400) {
+ UNUSED f32 scopedTemp;
+ timef = 0.5f + timesec / 28800.0f;
+ angle = 16384;
+ } // Between 8 p.m and 12 a.m
+ else {
+ timef = (timesec - 72000) / 28800.0f;
+ angle = 16384;
+ }
+
+ shadow->unk26 = 0x8000 - ((s16)(angle * timef) + 0x6000);
+}
+
+void mActorShadow_GetGroundAverageAngle(ShadowInfo* shadow) {
+ static xyz_t angle_range_table[4] = {
+ { 10.0f, 0.0f, 10.0f },
+ { 10.0f, 0.0f, -10.0f },
+ { -10.0f, 0.0f, 10.0f },
+ { -10.0f, 0.0f, -10.0f },
+ };
+
+ s32 x = 0;
+ s32 y = 0;
+ s32 z = 0;
+ s32 i;
+
+ for (i = 0; i < 4; i++) {
+ xyz_t pos = shadow->position;
+ s_xyz sangle = { 0, 0, 0 };
+
+ pos.x += angle_range_table[i].x;
+ pos.y += angle_range_table[i].y;
+ pos.z += angle_range_table[i].z;
+
+ mCoBG_GetBgY_AngleS_FromWpos(&sangle, pos, 0.0f);
+
+ x += sangle.x;
+ y += sangle.y;
+ z += sangle.z;
+ }
+
+ shadow->unk20 = x >> 2;
+ shadow->unk22 = y >> 2;
+ shadow->unk24 = z >> 2;
+}
+
+void mActorShadow_GetDistanceRate(ShadowInfo* shadow, f32 rate) {
+ f32 xcalc;
+ f32 disty;
+ f32 calcRate;
+
+ disty = shadow->groundY <= shadow->position.y ? shadow->position.y - shadow->groundY
+ : -(shadow->position.y - shadow->groundY);
+ xcalc = 100.0f + rate;
+
+ if (xcalc < disty) {
+ shadow->unk14 = 0.6f;
+ shadow->unk18 = 0;
+ return;
+ }
+
+ calcRate = (xcalc - disty) / xcalc;
+ shadow->unk14 = (((0.04f * 10.0f) * calcRate) + 0.6f);
+ shadow->unk18 = 1 * calcRate;
+}
+
+f32 mActorShadow_GetAbsBigger(f32 a, f32 b) {
+ f32 absA;
+ f32 absB;
+ absA = ABS(a);
+ absB = ABS(b);
+
+ if (absA > absB) {
+ return absA;
+ }
+ return absB;
+}
+
+void mActorShadow_RadiusScaleRate(Actor* actor, ShadowInfo* shadow) {
+ f32 abs = mActorShadow_GetAbsBigger(actor->shape.shadowSizeX, actor->shape.shadowSizeZ);
+ shadow->unk10 = (abs / 19.0f) * 0.018f;
+}
+
+void mActorShadow_GetShadowTopPos_GetSlideS(ShadowInfo* shadow) {
+ xyz_t wpos;
+ xyz_t base;
+ f32 bgY;
+
+ if (shadow->kind == 0) {
+ base.x = 0.0f;
+ base.y = 0.0f;
+ base.z = -40.0f;
+ sMath_RotateY(&base, BINANG_TO_RAD(shadow->unk26));
+ wpos.x = shadow->position.x + base.x;
+ wpos.y = shadow->position.y + base.y;
+ wpos.z = shadow->position.z + base.z;
+ bgY = mCoBG_GetShadowBgY_AngleS_FromWpos(NULL, wpos, 0.0f);
+ if ((shadow->position.y - bgY) > 20.0f) {
+ shadow->unk34 = 28;
+ return;
+ }
+ }
+ shadow->unk34 = 0;
+}
+
+Gfx* mActorShadow_SetTexScroll(Actor* actor, ShadowInfo* shadow, Game* game) {
+ s32 tempShapex2;
+ u32 y1 = 0;
+ u32 x1 = 0;
+ u32 y2 = 0;
+ s32 step;
+
+ tempShapex2 = actor->shape.unk_20;
+ if (tempShapex2 < shadow->unk34) {
+ step = 13;
+ } else if (tempShapex2 > shadow->unk34) {
+ step = -13;
+ } else {
+ step = 0;
+ }
+
+ mActorShadow_TileScroll2(&x1, &y1, 0, 0, 0, 0, 32, 16, &actor->shape.unk_20, &y2, step, 0, shadow->unk34, 0, 32, 16,
+ game);
+}
+
+void mActorShadow_GetLastAlphaScale(f32* scale, u8* alpha, Actor* actor, ShadowInfo* shadow) {
+ f32 alphaCalc = shadow->unk1C * shadow->unk18 * actor->shape.shadowAlphaRate * 0.75f;
+
+ *scale = shadow->unk10 * shadow->unk14 * actor->shape.shadowSizeRate;
+
+ if (shadow->kind == 1) {
+ alphaCalc *= 0.7f;
+ }
+ *alpha = alphaCalc;
+}
+
+#define AC_GCN_OPEN_DISP(gfxCtx) \
+ { \
+ GraphicsContext* __gfxCtx = gfxCtx; \
+ int __gfx_opened = 0; \
+ do { \
+ } while (0)
+
+#define AC_GCN_CLOSE_DISP(gfxCtx) \
+ (void)__gfx_opened; \
+ } \
+ do { \
+ } while (0)
+
+void mActorShadow_DrawActorShadow(Actor* actor, ShadowInfo* shadow, Game* game, f32 rad, s32 id, xyz_t ofs) {
+ Game_Play* play = (Game_Play*)game;
+ u8 alpha;
+ f32 scale;
+ u8 r;
+ u8 g;
+ u8 b;
+ f32 yAdjust;
+ s32 scene = common_data.sceneNo;
+
+ mActorShadow_GetLastAlphaScale(&scale, &alpha, actor, shadow);
+
+ AC_GCN_OPEN_DISP(play->state.gfxCtx);
+
+ _texture_z_light_fog_prim_shadow(play->state.gfxCtx);
+
+ yAdjust = (scene == 19 || scene == 27 || scene == 28 || scene == 34) ? 0.5f
+ : ((scene == 15 || scene == 16) ? 0.6f : 2.0f);
+
+ switch (actor->shape.forceShadow) {
+ f32 x;
+ f32 y;
+ f32 z;
+ case 1:
+ x = actor->shape.shadowPosition->x + ofs.x;
+ y = actor->shape.shadowPosition->y + yAdjust + ofs.y;
+ z = actor->shape.shadowPosition->z + ofs.z;
+ Matrix_translate(x, y, z, 0);
+ break;
+ default:
+ x = shadow->position.x + ofs.x;
+ y = shadow->groundY + yAdjust + ofs.y;
+ z = shadow->position.z + ofs.z;
+ Matrix_translate(x, y, z, 0);
+ break;
+ }
+
+ switch (actor->shape.forceShadow) {
+ case 1:
+ Matrix_RotateZ(0, 1);
+ Matrix_RotateX(0, 1);
+ break;
+ default:
+ Matrix_RotateZ(shadow->unk24, 1);
+ Matrix_RotateX(shadow->unk20, 1);
+ break;
+ }
+
+ if ((shadow->kind == 0) && (id == 0)) {
+ Matrix_RotateY(shadow->unk26, 1);
+ }
+
+ switch (id) {
+ case 1:
+ Matrix_scale(shadow->unk10, shadow->unk10, rad, 1);
+ break;
+ default:
+ switch (actor->shape.forceShadow) {
+ case 1:
+ Matrix_scale(shadow->unk10, shadow->unk10, shadow->unk10, 1);
+ break;
+ default:
+ Matrix_scale(scale, scale, scale, 1);
+ break;
+ }
+ break;
+ }
+
+ gSPMatrix(SHADOW_DISP++, _Matrix_to_Mtx_new(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ mEnv_GetShadowPrimColor_Light(&r, &g, &b, &play->state);
+ gDPSetPrimColor(SHADOW_DISP++, 0, 0xFF, r, g, b, (u8)alpha);
+
+ if ((shadow->kind == 0) && (id == 0)) {
+ Gfx* texscroll = mActorShadow_SetTexScroll(actor, shadow, &play->state);
+ if (texscroll != NULL) {
+ gSPSegment(SHADOW_DISP++, 0x08, texscroll);
+ gSPDisplayList(SHADOW_DISP++, ef_shadow_out_modelT);
+ }
+ } else {
+ gSPDisplayList(SHADOW_DISP++, ef_shadow_in_modelT);
+ }
+
+ AC_GCN_CLOSE_DISP(play->state.gfxCtx);
+}
+
+void mActorShadow_GetShadowPosition(Actor* actor, xyz_t* position) {
+ if (actor->shape.shadowPosition != NULL) {
+ *position = *actor->shape.shadowPosition;
+ } else {
+ *position = actor->world.pos;
+ }
+}
+
+s32 mActorShadow_GetShadowKind(void) {
+ if (!(FI_GET_TYPE(mFI_GetFieldId()))) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+f32 mAc_GetShadowGroundY_NoneForce(ShadowInfo* shadow) {
+ f32 res = mCoBG_GetShadowBgY_AngleS_FromWpos(NULL, shadow->position, 0.0f);
+ return res;
+}
+
+f32 mAc_GetShadowGroundY_Force(ShadowInfo* shadow) {
+ return mCoBG_GetBgY_OnlyCenter_FromWpos2(shadow->position, 0.0f);
+}
+
+void mAc_DecideShadowRadius_IamNotFish(ShadowInfo* shadow, Actor* actor, f32* radius) {
+ mActorShadow_RadiusScaleRate(actor, shadow);
+ *radius = 0.01f;
+}
+
+void mAc_DecideShadowRadius_IamFish(ShadowInfo* shadow, Actor* actor, f32* radius) {
+ shadow->unk10 = (actor->shape.shadowSizeX / 19.0f) * 0.018f;
+ *radius = (actor->shape.shadowSizeZ / 19.0f) * 0.018f;
+}
+
+void mAc_ActorShadowDraw_ShadowDrawFlagOff(UNUSED Actor* actor, UNUSED Game_Play* play, UNUSED s32 arg2,
+ UNUSED xyz_t arg3, UNUSED f32 arg6) {
+}
+
+typedef f32 (*GetGroundYProc)(ShadowInfo*);
+typedef void (*RadiusProc)(ShadowInfo*, Actor*, f32*);
+typedef void (*ShadowProc)(Actor* actor, Game_Play* play, s32 arg2, xyz_t arg3, f32 arg6);
+
+void mAc_ActorShadowDraw_ShadowDrawFlagOn(Actor* actor, Game_Play* play, s32 proc, xyz_t pos, f32 rate) {
+ static RadiusProc set_raius_proc[] = {
+ mAc_DecideShadowRadius_IamNotFish,
+ mAc_DecideShadowRadius_IamFish,
+ };
+
+ static GetGroundYProc get_ground_y_proc[] = {
+ mAc_GetShadowGroundY_NoneForce,
+ mAc_GetShadowGroundY_Force,
+ };
+
+ ShadowInfo shadow;
+ UNUSED s32 pad;
+ f32 rad = 0.01f;
+
+ bzero(&shadow, sizeof(ShadowInfo));
+
+ shadow.kind = mActorShadow_GetShadowKind();
+ mActorShadow_GetShadowPosition(actor, &shadow.position);
+ mActorShadow_AdjustRate(&actor->shape.shadowSizeRate);
+ mActorShadow_AdjustRate(&actor->shape.shadowAlphaRate);
+
+ shadow.groundY = get_ground_y_proc[actor->shape.forceShadow & 1](&shadow);
+
+ mActorShadow_GetTimeAngleY_TimeAlpha(&shadow, play);
+ mActorShadow_GetGroundAverageAngle(&shadow);
+ mActorShadow_GetDistanceRate(&shadow, rate);
+ set_raius_proc[proc & 1](&shadow, actor, &rad);
+ mActorShadow_GetShadowTopPos_GetSlideS(&shadow);
+ mActorShadow_DrawActorShadow(actor, &shadow, &play->state, rad, proc, pos);
+ actor->shape.forceShadow = FALSE;
+}
+
+void mAc_ActorShadowDraw(Actor* actor, Game_Play* play, s32 arg2, xyz_t arg3, f32 arg6) {
+ static ShadowProc shadwo_draw_proc[] = {
+ mAc_ActorShadowDraw_ShadowDrawFlagOff,
+ mAc_ActorShadowDraw_ShadowDrawFlagOn,
+ };
+
+ if (actor->name == 0x4A) {
+ mActorShadow_UnSetForceShadowPos(actor);
+ actor->shape.shadowPosition = &actor->world.pos;
+ }
+
+ shadwo_draw_proc[actor->shape.drawShadow & 1](actor, play, arg2, arg3, arg6);
+ actor->shape.shadowPosition = &actor->world.pos;
+}
+
+xyz_t mActorShadow_offset0 = {
+ 0.0f,
+ 0.0f,
+ 0.0f,
+};
+
+void mActorShadow_SetForceShadowPos(Actor* actor, xyz_t* pos) {
+ actor->shape.forceShadow = TRUE;
+ actor->shape.shadowPosition = pos;
+}
+
+void mActorShadow_UnSetForceShadowPos(Actor* actor) {
+ actor->shape.forceShadow = FALSE;
+ actor->shape.shadowPosition = &actor->world.pos;
+}
+
+void mAc_NormalActorShadow(Actor* actor, Game_Play* play, f32 rad) {
+ mAc_ActorShadowDraw(actor, play, 0, mActorShadow_offset0, rad);
+}
+
+void mAc_UnagiActorShadow(Actor* actor, Game_Play* play, xyz_t pos) {
+ mAc_ActorShadowDraw(actor, play, 1, pos, 1.0f);
+}
+
+void mAc_ActorShadowCircle(Actor* actor, UNUSED LightsN* lights, Game_Play* play) {
+ mAc_ActorShadowDraw(actor, play, 0, mActorShadow_offset0, 1.0f);
+}
+
+void mAc_ActorShadowEllipse(Actor* actor, UNUSED LightsN* lights, Game_Play* play) {
+ mAc_ActorShadowDraw(actor, play, 0, mActorShadow_offset0, 1.0f);
+}
diff --git a/src/overlays/gamestates/ovl_play/m_play.c b/src/overlays/gamestates/ovl_play/m_play.c
index 198d4c2..17d5c53 100644
--- a/src/overlays/gamestates/ovl_play/m_play.c
+++ b/src/overlays/gamestates/ovl_play/m_play.c
@@ -549,21 +549,21 @@ void func_80803810_jp(Game_Play* game_play, GraphicsContext* gfxCtx) {
gSPSegment(POLY_XLU_DISP++, 0x00, NULL);
gSPSegment(OVERLAY_DISP++, 0x00, NULL);
gSPSegment(UNK_2B0_DISP++, 0x00, NULL);
- gSPSegment(UNK_2C0_DISP++, 0x00, NULL);
+ gSPSegment(SHADOW_DISP++, 0x00, NULL);
gSPSegment(LIGHT_DISP++, 0x00, NULL);
gSPSegment(POLY_OPA_DISP++, 0x04, temp_v0);
gSPSegment(POLY_XLU_DISP++, 0x04, temp_v0);
gSPSegment(OVERLAY_DISP++, 0x04, temp_v0);
gSPSegment(UNK_2B0_DISP++, 0x04, temp_v0);
- gSPSegment(UNK_2C0_DISP++, 0x04, temp_v0);
+ gSPSegment(SHADOW_DISP++, 0x04, temp_v0);
gSPSegment(LIGHT_DISP++, 0x04, temp_v0);
gSPSegment(POLY_OPA_DISP++, 0x02, game_play->unk_010C);
gSPSegment(POLY_XLU_DISP++, 0x02, game_play->unk_010C);
gSPSegment(OVERLAY_DISP++, 0x02, game_play->unk_010C);
gSPSegment(UNK_2B0_DISP++, 0x02, game_play->unk_010C);
- gSPSegment(UNK_2C0_DISP++, 0x02, game_play->unk_010C);
+ gSPSegment(SHADOW_DISP++, 0x02, game_play->unk_010C);
gSPSegment(LIGHT_DISP++, 0x02, game_play->unk_010C);
CLOSE_DISPS(gfxCtx);
diff --git a/yamls/jp/code.yaml b/yamls/jp/code.yaml
index cc299ca..bec6a8f 100644
--- a/yamls/jp/code.yaml
+++ b/yamls/jp/code.yaml
@@ -11,7 +11,7 @@
- [0x6792F0, asm, code/6792F0]
- [0x67A020, c, code/m_actor]
- [0x67C6B0, c, code/m_actor_dlftbls]
- - [0x67C890, asm, code/m_actor_shadow]
+ - [0x67C890, c, code/m_actor_shadow]
- [0x67D890, asm, code/67D890]
- [0x67E840, asm, code/67E840]
- [0x683030, asm, code/683030]
@@ -140,7 +140,7 @@
- [0x7248D0, data, code/7248D0]
- [0x724910, .data, code/m_actor]
- [0x724930, .data, code/m_actor_dlftbls]
- - [0x726260, data, code/m_actor_shadow]
+ - [0x726260, .data, code/m_actor_shadow]
- [0x7262C0, data, code/7262C0]
- [0x7279F0, data, code/7279F0]
- [0x728340, .data, code/m_collision_obj]
@@ -183,7 +183,7 @@
- [0x739E00, rodata, code/739E00]
- [0x739E50, .rodata, code/m_actor]
- [0x739EA0, .rodata, code/m_actor_dlftbls]
- - [0x739EF0, rodata, code/739EF0]
+ - [0x739EF0, .rodata, code/m_actor_shadow]
- [0x739F20, rodata, code/739F20]
- [0x739F70, rodata, code/739F70]
- [0x739FA0, rodata, code/739FA0]