Transform tagging for snow weather effect

This commit is contained in:
Mr-Wiseguy 2024-03-11 00:13:32 -04:00
parent eeeabba64d
commit 38680d7171
4 changed files with 259 additions and 6 deletions

View File

@ -1,8 +1,7 @@
#include "patches.h" #include "patches.h"
#include "transform_ids.h" #include "transform_ids.h"
#include "overlays/actors/ovl_En_Test7/z_en_test7.h" #include "overlays/actors/ovl_En_Test7/z_en_test7.h"
#include "overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h"
#define THIS ((EnTest7*)thisx)
// Decomp renames, TODO update decomp and remove these // Decomp renames, TODO update decomp and remove these
#define gSoaringWarpCsWindCapsuleTexAnim gameplay_keep_Matanimheader_0815D0 #define gSoaringWarpCsWindCapsuleTexAnim gameplay_keep_Matanimheader_0815D0
@ -18,7 +17,7 @@ extern Gfx gSoaringWarpCsWindCapsuleDL[];
void EnTest7_Draw(Actor* thisx, PlayState* play) { void EnTest7_Draw(Actor* thisx, PlayState* play) {
s32 pad[2]; s32 pad[2];
EnTest7* this = THIS; EnTest7* this = (EnTest7*)thisx;
s32 sp40; s32 sp40;
OPEN_DISPS(play->state.gfxCtx); OPEN_DISPS(play->state.gfxCtx);
@ -74,4 +73,255 @@ void EnTest7_Draw(Actor* thisx, PlayState* play) {
CLOSE_DISPS(play->state.gfxCtx); 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);
}

View File

@ -4,6 +4,8 @@
// TODO fix renaming symbols in patch recompilation // TODO fix renaming symbols in patch recompilation
#define osRecvMesg osRecvMesg_recomp #define osRecvMesg osRecvMesg_recomp
#define osSendMesg osSendMesg_recomp #define osSendMesg osSendMesg_recomp
#define sinf __sinf_recomp
#define cosf __cosf_recomp
#include "global.h" #include "global.h"
#include "rt64_extended_gbi.h" #include "rt64_extended_gbi.h"

View File

@ -2,6 +2,7 @@ __start = 0x80000000;
/* Static symbols that aren't in the elf */ /* Static symbols that aren't in the elf */
sSceneEntranceTable = 0x801C5720; sSceneEntranceTable = 0x801C5720;
D_808DE5B0 = 0x808DE5B0;
/* Dummy addresses that get recompiled into function calls */ /* Dummy addresses that get recompiled into function calls */
recomp_puts = 0x8F000000; recomp_puts = 0x8F000000;
@ -18,3 +19,5 @@ recomp_get_target_framerate = 0x8F000028;
recomp_get_targeting_mode = 0x8F00002C; recomp_get_targeting_mode = 0x8F00002C;
recomp_get_bgm_volume = 0x8F000030; recomp_get_bgm_volume = 0x8F000030;
recomp_get_low_health_beeps_enabled = 0x8F000034; recomp_get_low_health_beeps_enabled = 0x8F000034;
__sinf_recomp = 0x8F000038;
__cosf_recomp = 0x8F00003C;

View File

@ -52,10 +52,8 @@ void bind_atomic(Rml::DataModelConstructor& constructor, Rml::DataModelHandle ha
constructor.BindFunc(name, constructor.BindFunc(name,
[atomic_val](Rml::Variant& out) { [atomic_val](Rml::Variant& out) {
out = atomic_val->load(); out = atomic_val->load();
printf("out: %s\n", out.Get<std::string>().c_str());
}, },
[atomic_val, handle, name](const Rml::Variant& in) mutable { [atomic_val, handle, name](const Rml::Variant& in) mutable {
printf("in: %s\n", in.Get<std::string>().c_str());
atomic_val->store(in.Get<T>()); atomic_val->store(in.Get<T>());
handle.DirtyVariable(name); handle.DirtyVariable(name);
} }