From 4a679da4895cf66b68dd90a601a4c0c9e41e5409 Mon Sep 17 00:00:00 2001 From: Prakxo <87568477+Prakxo@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:55:22 +0100 Subject: m_actor_shadow OK (#142) * werk * more werk * m_actor_shadow OK * format * protos fix * jenkins happy --- include/gfx.h | 4 +- include/m_actor.h | 16 +- include/m_actor_shadow.h | 73 ++++-- include/m_collision_bg.h | 4 +- include/m_field_info.h | 1 + include/m_kankyo.h | 6 +- include/m_rcp.h | 2 +- include/sys_math3d.h | 6 +- linker_scripts/jp/symbol_addrs_code.txt | 2 +- linker_scripts/jp/undefined_syms.ld | 4 +- src/code/game.c | 6 +- src/code/m_actor.c | 20 +- src/code/m_actor_shadow.c | 414 ++++++++++++++++++++++++++++++ src/overlays/gamestates/ovl_play/m_play.c | 6 +- yamls/jp/code.yaml | 6 +- 15 files changed, 503 insertions(+), 67 deletions(-) create mode 100644 src/code/m_actor_shadow.c 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] -- cgit v1.2.3