From 38680d7171a45371130670fa331572cee7b604a6 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Mon, 11 Mar 2024 00:13:32 -0400 Subject: [PATCH] Transform tagging for snow weather effect --- patches/effect_transform_tagging.c | 258 ++++++++++++++++++++++++++++- patches/patches.h | 2 + patches/syms.ld | 3 + src/ui/ui_config.cpp | 2 - 4 files changed, 259 insertions(+), 6 deletions(-) diff --git a/patches/effect_transform_tagging.c b/patches/effect_transform_tagging.c index 7b9d8f8..a9c34e1 100644 --- a/patches/effect_transform_tagging.c +++ b/patches/effect_transform_tagging.c @@ -1,8 +1,7 @@ #include "patches.h" #include "transform_ids.h" #include "overlays/actors/ovl_En_Test7/z_en_test7.h" - -#define THIS ((EnTest7*)thisx) +#include "overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h" // Decomp renames, TODO update decomp and remove these #define gSoaringWarpCsWindCapsuleTexAnim gameplay_keep_Matanimheader_0815D0 @@ -18,7 +17,7 @@ extern Gfx gSoaringWarpCsWindCapsuleDL[]; void EnTest7_Draw(Actor* thisx, PlayState* play) { s32 pad[2]; - EnTest7* this = THIS; + EnTest7* this = (EnTest7*)thisx; s32 sp40; OPEN_DISPS(play->state.gfxCtx); @@ -74,4 +73,255 @@ void EnTest7_Draw(Actor* thisx, PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } -#undef TEST +extern f32 D_808DE5B0; +extern Gfx gEffDust5Tex[]; +extern Gfx gEffDustDL[]; + +// Use an unused byte in the particle's struct to track whether its interpolation should be skipped this frame. +#define particle_skipped(particle) \ + ((&(particle).unk_1C)[1]) + +// @recomp Patched to record when a particle is moved to skip interpolation. +void func_808DC454(ObjectKankyo* this, PlayState* play) { + s16 i; + s32 pad1; + f32 phi_f20; + f32 spD0; + f32 spCC; + f32 spC8; + f32 spC4; + f32 spC0; + f32 spBC; + f32 temp_f0_4; + f32 temp_f22; + f32 temp_f24; + f32 temp_f28; + f32 x = play->view.at.x - play->view.eye.x; + f32 y = play->view.at.y - play->view.eye.y; + f32 z = play->view.at.z - play->view.eye.z; + f32 magnitude = sqrtf(SQ(x) + SQ(y) + SQ(z)); + f32 temp_120 = 120.0f; + f32 temp_f30; + Vec3f sp88; + s32 pad; + + spD0 = x / magnitude; + spCC = y / magnitude; + spC8 = z / magnitude; + + for (i = 0; i < play->envCtx.precipitation[PRECIP_SNOW_CUR]; i++) { + switch (this->unk_14C[i].unk_1C) { + case 0: + this->unk_14C[i].unk_00 = play->view.eye.x + (spD0 * 120.0f); + this->unk_14C[i].unk_04 = play->view.eye.y + (spCC * 120.0f); + this->unk_14C[i].unk_08 = play->view.eye.z + (spC8 * 120.0f); + this->unk_14C[i].unk_0C = (Rand_ZeroOne() - 0.5f) * (2.0f * temp_120); + + temp_f22 = (Camera_GetCamDirPitch(GET_ACTIVE_CAM(play)) * 0.004f) + 60.0f; + if (temp_f22 < 20.0f) { + temp_f22 = 20.0f; + } + + if (this->unk_114E == 0) { + this->unk_14C[i].unk_10 = temp_f22; + } else { + this->unk_14C[i].unk_10 += temp_f22; + if (play->envCtx.precipitation[PRECIP_SNOW_CUR] == ((u32)i + 1)) { + this->unk_114E = 0; + } + } + + this->unk_14C[i].unk_14 = (Rand_ZeroOne() - 0.5f) * (2.0f * temp_120); + if (play->envCtx.precipitation[PRECIP_SOS_MAX] == 0) { + this->unk_14C[i].unk_18 = (Rand_ZeroOne() * 3.0f) + 1.0f; + } else { + this->unk_14C[i].unk_18 = (Rand_ZeroOne() * 3.0f) + 8.0f; + } + particle_skipped(this->unk_14C[i]) = true; + this->unk_14C[i].unk_1C++; + break; + + case 1: + temp_f24 = play->view.eye.x + (spD0 * 120.0f); + temp_f28 = play->view.eye.y + (spCC * 120.0f); + temp_f30 = play->view.eye.z + (spC8 * 120.0f); + + magnitude = sqrtf((f32)SQ(play->envCtx.windDirection.x) + SQ(play->envCtx.windDirection.y) + + SQ(play->envCtx.windDirection.z)); + if (magnitude == 0.0f) { + magnitude = 0.001f; + } + spC4 = -play->envCtx.windDirection.x / magnitude; + spC0 = -play->envCtx.windDirection.y / magnitude; + spBC = -play->envCtx.windDirection.z / magnitude; + + if (i == 0) { + this->unk_144 += 0.049999997f * Rand_ZeroOne(); + this->unk_148 += 0.049999997f * Rand_ZeroOne(); + } + + phi_f20 = play->envCtx.windSpeed / 120.0f; + phi_f20 = CLAMP(phi_f20, 0.0f, 1.0f); + + this->unk_14C[i].unk_0C += sinf((this->unk_144 + (i * 100.0f)) * 0.01f) + (spC4 * 10.0f * phi_f20); + this->unk_14C[i].unk_14 += cosf((this->unk_148 + (i * 100.0f)) * 0.01f) + (spBC * 10.0f * phi_f20); + this->unk_14C[i].unk_10 -= this->unk_14C[i].unk_18 - (spC0 * 3.0f * (play->envCtx.windSpeed / 100.0f)); + + temp_f22 = (-Camera_GetCamDirPitch(GET_ACTIVE_CAM(play)) * 0.012f) + 40.0f; + if (temp_f22 < -40.0f) { + temp_f22 = -40.0f; + } + + if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f24) > temp_120) { + this->unk_14C[i].unk_00 = temp_f24 - temp_120; + // @recomp Skip interpolation. + particle_skipped(this->unk_14C[i]) = true; + } + + if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f24) < -temp_120) { + this->unk_14C[i].unk_00 = temp_f24 + temp_120; + // @recomp Skip interpolation. + particle_skipped(this->unk_14C[i]) = true; + } + + sp88.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C; + sp88.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10; + sp88.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14; + + phi_f20 = Math_Vec3f_DistXZ(&sp88, &play->view.eye) / 200.0f; + phi_f20 = CLAMP(phi_f20, 0.0f, 1.0f); + temp_f0_4 = 100.0f + phi_f20 + 60.0f; + + if (temp_f0_4 < (this->unk_14C[i].unk_04 + (this->unk_14C[i].unk_10) - temp_f28)) { + this->unk_14C[i].unk_04 = temp_f28 - temp_f0_4; + // @recomp Skip interpolation. + particle_skipped(this->unk_14C[i]) = true; + } + + if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) < -temp_f0_4) { + this->unk_14C[i].unk_04 = temp_f28 + temp_f0_4; + // @recomp Skip interpolation. + particle_skipped(this->unk_14C[i]) = true; + } + + if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f30) > temp_120) { + this->unk_14C[i].unk_08 = temp_f30 - temp_120; + // @recomp Skip interpolation. + particle_skipped(this->unk_14C[i]) = true; + } + + if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f30) < -temp_120) { + this->unk_14C[i].unk_08 = temp_f30 + temp_120; + // @recomp Skip interpolation. + particle_skipped(this->unk_14C[i]) = true; + } + + if ((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) < ((play->view.eye.y - temp_f22) - 40.0f)) { + this->unk_14C[i].unk_1C = 0; + } + break; + } + } +} + +void func_808DD3C8(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + ObjectKankyo* this = (ObjectKankyo*)thisx; + Vec3f worldPos; + Vec3f screenPos; + s16 i; + u8 pad2; + u8 spB4; + f32 temp_f0; + u8 sp68; + s32 pad; + f32 temp_f2; + f32 tempf; + + if ((play->cameraPtrs[CAM_ID_MAIN]->stateFlags & CAM_STATE_UNDERWATER) || ((u8)play->envCtx.stormState == 0)) { + return; + } + + OPEN_DISPS(play->state.gfxCtx); + + spB4 = false; + + if (this->actor.params == 3) { + // @recomp Manual relocation, TODO remove when the recompiler handles this automatically. + f32* D_808DE5B0_ptr = actor_relocate(thisx, &D_808DE5B0); + + temp_f0 = func_80173B48(&play->state) / 1.4e7f; + temp_f0 = CLAMP(temp_f0, 0.0f, 1.0f); + Math_SmoothStepToF(D_808DE5B0_ptr, temp_f0, 0.2f, 0.1f, 0.001f); + + sp68 = play->envCtx.precipitation[PRECIP_SNOW_CUR]; + sp68 *= *D_808DE5B0_ptr; + + if ((play->envCtx.precipitation[PRECIP_SNOW_CUR] >= 32) && (sp68 < 32)) { + sp68 = 32; + } + } else { + sp68 = play->envCtx.precipitation[PRECIP_SNOW_CUR]; + } + + for (i = 0; i < sp68; i++) { + worldPos.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C; + worldPos.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10; + worldPos.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14; + + Play_GetScreenPos(play, &worldPos, &screenPos); + + // @recomp Render particles beyond the screen bounds. + if (true) { + // if ((screenPos.x >= 0.0f) && (screenPos.x < SCREEN_WIDTH) && (screenPos.y >= 0.0f) && + // (screenPos.y < SCREEN_HEIGHT)) { + if (!spB4) { + spB4 = true; + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 255); + gSPClearGeometryMode(POLY_XLU_DISP++, G_LIGHTING); + + POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0); + + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2); + gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG); + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffDust5Tex)); + } + + Matrix_Translate(worldPos.x, worldPos.y, worldPos.z, MTXMODE_NEW); + tempf = (i & 7) * 0.008f; + Matrix_Scale(0.05f + tempf, 0.05f + tempf, 0.05f + tempf, MTXMODE_APPLY); + temp_f2 = Math_Vec3f_DistXYZ(&worldPos, &play->view.eye) / 300.0f; + temp_f2 = ((1.0f < temp_f2) ? 0.0f : (((1.0f - temp_f2) > 1.0f) ? 1.0f : 1.0f - temp_f2)); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)(160.0f * temp_f2)); + + Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + // @recomp Check if the particle's interpolation should be skipped this frame. + if (particle_skipped(this->unk_14C[i])) { + // @recomp Tag the particle's transform to skip interpolation. + gEXMatrixGroupSimple(POLY_XLU_DISP++, actor_transform_id(thisx) + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_MTX_MODELVIEW); + } + else { + // @recomp Tag the particle's matrix to interpolate normally. + gEXMatrixGroupDecomposed(POLY_XLU_DISP++, actor_transform_id(thisx) + i, G_EX_PUSH, G_MTX_MODELVIEW, + G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR); + } + + gSPDisplayList(POLY_XLU_DISP++, gEffDustDL); + + // @recomp Pop the particle transform tag. + gEXPopMatrixGroup(POLY_XLU_DISP++); + } + + // @recomp Reset the particle's skip flag. + particle_skipped(this->unk_14C[i]) = false; + } + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/patches/patches.h b/patches/patches.h index 789ed3e..f39d43f 100644 --- a/patches/patches.h +++ b/patches/patches.h @@ -4,6 +4,8 @@ // TODO fix renaming symbols in patch recompilation #define osRecvMesg osRecvMesg_recomp #define osSendMesg osSendMesg_recomp +#define sinf __sinf_recomp +#define cosf __cosf_recomp #include "global.h" #include "rt64_extended_gbi.h" diff --git a/patches/syms.ld b/patches/syms.ld index 7e5c6a6..dc46b22 100644 --- a/patches/syms.ld +++ b/patches/syms.ld @@ -2,6 +2,7 @@ __start = 0x80000000; /* Static symbols that aren't in the elf */ sSceneEntranceTable = 0x801C5720; +D_808DE5B0 = 0x808DE5B0; /* Dummy addresses that get recompiled into function calls */ recomp_puts = 0x8F000000; @@ -18,3 +19,5 @@ recomp_get_target_framerate = 0x8F000028; recomp_get_targeting_mode = 0x8F00002C; recomp_get_bgm_volume = 0x8F000030; recomp_get_low_health_beeps_enabled = 0x8F000034; +__sinf_recomp = 0x8F000038; +__cosf_recomp = 0x8F00003C; diff --git a/src/ui/ui_config.cpp b/src/ui/ui_config.cpp index 60f55a4..b9a8d01 100644 --- a/src/ui/ui_config.cpp +++ b/src/ui/ui_config.cpp @@ -52,10 +52,8 @@ void bind_atomic(Rml::DataModelConstructor& constructor, Rml::DataModelHandle ha constructor.BindFunc(name, [atomic_val](Rml::Variant& out) { out = atomic_val->load(); - printf("out: %s\n", out.Get().c_str()); }, [atomic_val, handle, name](const Rml::Variant& in) mutable { - printf("in: %s\n", in.Get().c_str()); atomic_val->store(in.Get()); handle.DirtyVariable(name); }