Skip to content

Commit

Permalink
fix interpolation for kankyo particles and effects
Browse files Browse the repository at this point in the history
  • Loading branch information
Archez committed Nov 28, 2024
1 parent 77d69c5 commit a94aade
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
34 changes: 28 additions & 6 deletions mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ void DemoKakyo_LostWoodsSparkleActionFunc(DemoKankyo* this, PlayState* play) {
this->effects[i].posOffset.z = 0.0f;
this->effects[i].posBase.z = posCenterZ + repositionLimit;
}

// 2S2H [Interpolation] Skip particle interpolation on next frame
this->effects[i].epoch++;
}
break;

Expand Down Expand Up @@ -396,10 +399,17 @@ void DemoKakyo_MoonSparklesActionFunc(DemoKankyo* this, PlayState* play) {
}

if (((this->effects[i].posBase.x + this->effects[i].posOffset.x) - newEye.x) > halfScreenHeight) {
// 2S2H [Interpolation] Here and below, skip particle interpolation on next frame when positionmoves
if (ABS(this->effects[i].posBase.x - (newEye.x - halfScreenHeight)) >= 120.0f) {
this->effects[i].epoch++;
}
this->effects[i].posBase.x = newEye.x - halfScreenHeight;
}

if (((this->effects[i].posBase.x + this->effects[i].posOffset.x) - newEye.x) < -halfScreenHeight) {
if (ABS(this->effects[i].posBase.x - (newEye.x + halfScreenHeight)) >= 120.0f) {
this->effects[i].epoch++;
}
this->effects[i].posBase.x = newEye.x + halfScreenHeight;
}

Expand All @@ -413,18 +423,30 @@ void DemoKakyo_MoonSparklesActionFunc(DemoKankyo* this, PlayState* play) {

// I think this code is shifting the effects 1 frame -> half screen at a time to keep it in-view
if (halfScreenWidth < ((this->effects[i].posBase.y + this->effects[i].posOffset.y) - newEye.y)) {
if (ABS(this->effects[i].posBase.y - (newEye.y - halfScreenWidth)) >= 120.0f) {
this->effects[i].epoch++;
}
this->effects[i].posBase.y = newEye.y - halfScreenWidth;
}

if (((this->effects[i].posBase.y + this->effects[i].posOffset.y) - newEye.y) < -halfScreenWidth) {
if (ABS(this->effects[i].posBase.y - (newEye.y + halfScreenWidth)) >= 120.0f) {
this->effects[i].epoch++;
}
this->effects[i].posBase.y = newEye.y + halfScreenWidth;
}

if (((this->effects[i].posBase.z + this->effects[i].posOffset.z) - newEye.z) > halfScreenHeight) {
if (ABS(this->effects[i].posBase.z - (newEye.z - halfScreenHeight)) >= 120.0f) {
this->effects[i].epoch++;
}
this->effects[i].posBase.z = newEye.z - halfScreenHeight;
}

if (((this->effects[i].posBase.z + this->effects[i].posOffset.z) - newEye.z) < -halfScreenHeight) {
if (ABS(this->effects[i].posBase.z - (newEye.z + halfScreenHeight)) >= 120.0f) {
this->effects[i].epoch++;
}
this->effects[i].posBase.z = newEye.z + halfScreenHeight;
}

Expand Down Expand Up @@ -516,7 +538,6 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, PlayState* play2) {
gSPDisplayList(POLY_XLU_DISP++, gSunSparkleMaterialDL);

for (i = 0; i < play->envCtx.precipitation[PRECIP_SNOW_MAX]; i++) {
FrameInterpolation_RecordOpenChild(this, i);
worldPos.x = this->effects[i].posBase.x + this->effects[i].posOffset.x;
worldPos.y = this->effects[i].posBase.y + this->effects[i].posOffset.y;
worldPos.z = this->effects[i].posBase.z + this->effects[i].posOffset.z;
Expand All @@ -530,11 +551,12 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, PlayState* play2) {
xMin = OTRGetDimensionFromLeftEdge(xMin);
xMax = OTRGetDimensionFromRightEdge(xMax);
}
// #pragma endregion
// #endregion

// checking if particle is on screen
if ((screenPos.x >= xMin) && (screenPos.x < xMax) && (screenPos.y >= 0.0f) &&
(screenPos.y < SCREEN_HEIGHT)) {
FrameInterpolation_RecordOpenChild(&this->effects[i], this->effects[i].epoch);
Matrix_Translate(worldPos.x, worldPos.y, worldPos.z, MTXMODE_NEW);
scaleAlpha = this->effects[i].alpha / 50.0f;
if (scaleAlpha > 1.0f) {
Expand Down Expand Up @@ -591,8 +613,8 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, PlayState* play2) {
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gSunSparkleModelDL);
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}

CLOSE_DISPS(play->state.gfxCtx);
Expand All @@ -617,7 +639,6 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, PlayState* play2) {
Gfx_SetupDL25_Xlu(gfxCtx);

for (i = 0; i < play->envCtx.precipitation[PRECIP_SNOW_MAX]; i++) {
FrameInterpolation_RecordOpenChild(this, i);
worldPos.x = this->effects[i].posBase.x + this->effects[i].posOffset.x;
worldPos.y = this->effects[i].posBase.y + this->effects[i].posOffset.y;
worldPos.z = this->effects[i].posBase.z + this->effects[i].posOffset.z;
Expand All @@ -631,11 +652,12 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, PlayState* play2) {
xMin = OTRGetDimensionFromLeftEdge(xMin);
xMax = OTRGetDimensionFromRightEdge(xMax);
}
// #pragma endregion
// #endregion

// checking if effect is on screen
if ((screenPos.x >= xMin) && (screenPos.x < xMax) && (screenPos.y >= 0.0f) &&
(screenPos.y < SCREEN_HEIGHT)) {
FrameInterpolation_RecordOpenChild(&this->effects[i], this->effects[i].epoch);
Matrix_Translate(worldPos.x, worldPos.y, worldPos.z, MTXMODE_NEW);
alphaScale = this->effects[i].alpha / 50.0f;
if (alphaScale > 1.0f) {
Expand Down Expand Up @@ -680,8 +702,8 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, PlayState* play2) {
} else {
gSPDisplayList(POLY_XLU_DISP++, gLightOrbModelDL);
}
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}

CLOSE_DISPS(gfxCtx);
Expand Down
2 changes: 2 additions & 0 deletions mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ typedef struct {
/* 0x4A */ u16 LostWoodsSkyFishPosOffsetMax; // The x-z range the lost woods skyfish oscillates around player. random value between 15-65
/* 0x4C */ f32 LostWoodsSkyFishSpeedY; // the y speed (angular velocity) the lost woods skyfish oscillates around player.
/* 0x50 */ u16 pad50; // unused, always assigned to 0, nothing else in this actor uses it
// 2S2H [Port]
/* */ s16 epoch;
} DemoKankyoEffect; // size = 0x54

#define DEMOKANKYO_EFFECT_COUNT 64
Expand Down
22 changes: 12 additions & 10 deletions mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) {
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;
FrameInterpolation_RecordOpenChild(this, i);

Play_GetScreenPos(play, &worldPos, &screenPos);

// #region 2S2H [Cosmetic] Increase snow render area for widescreen
Expand All @@ -551,9 +551,10 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) {
xMin = OTRGetDimensionFromLeftEdge(xMin);
xMax = OTRGetDimensionFromRightEdge(xMax);
}
// #pragma endregion
// #endregion

if ((screenPos.x >= xMin) && (screenPos.x < xMax) && (screenPos.y >= 0.0f) && (screenPos.y < SCREEN_HEIGHT)) {
FrameInterpolation_RecordOpenChild(&this->unk_14C[i], 0);
if (!spB4) {
spB4 = true;

Expand Down Expand Up @@ -581,8 +582,8 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) {

gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffDustDL);
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}

CLOSE_DISPS(play->state.gfxCtx);
Expand Down Expand Up @@ -624,7 +625,7 @@ void func_808DD970(Actor* thisx, PlayState* play2) {
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;
FrameInterpolation_RecordOpenChild(this, i);

Play_GetScreenPos(play, &worldPos, &screenPos);

// #region 2S2H [Cosmetic] Increase deep underwater dust render area for widescreen
Expand All @@ -634,9 +635,10 @@ void func_808DD970(Actor* thisx, PlayState* play2) {
xMin = OTRGetDimensionFromLeftEdge(xMin);
xMax = OTRGetDimensionFromRightEdge(xMax);
}
// #pragma endregion
// #endregion

if ((screenPos.x >= xMin) && (screenPos.x < xMax) && (screenPos.y >= 0.0f) && (screenPos.y < SCREEN_HEIGHT)) {
FrameInterpolation_RecordOpenChild(&this->unk_14C[i], 0);
Matrix_Translate(worldPos.x, worldPos.y, worldPos.z, MTXMODE_NEW);
Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY);
temp_f0 = Math_Vec3f_DistXYZ(&worldPos, &play->view.eye);
Expand All @@ -657,8 +659,8 @@ void func_808DD970(Actor* thisx, PlayState* play2) {
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2);
gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG);
gSPDisplayList(POLY_XLU_DISP++, gEffDustDL);
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}

CLOSE_DISPS(play->state.gfxCtx);
Expand Down Expand Up @@ -693,8 +695,8 @@ void func_808DDE9C(Actor* thisx, PlayState* play2) {
temp_f22 = this->unk_14C[0].unk_04 + ((Rand_ZeroOne() - 0.7f) * this->unk_144);
temp_f2 = this->unk_14C[0].unk_08 + ((Rand_ZeroOne() - 0.7f) * this->unk_144);

FrameInterpolation_RecordOpenChild(this, i);
if (!((temp_f20 < -252.0f) && (temp_f20 > -500.0f) && (temp_f2 > 3820.0f) && (temp_f2 < 4150.0f))) {
FrameInterpolation_RecordOpenChild(this, i);
Matrix_Translate(temp_f20, temp_f22, temp_f2, MTXMODE_NEW);

gSPMatrix(POLY_XLU_DISP++, D_01000000_TO_SEGMENTED, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
Expand All @@ -710,14 +712,13 @@ void func_808DDE9C(Actor* thisx, PlayState* play2) {

gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gFallingRainDropDL);
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}

phi_s5 = false;
if (player->actor.floorHeight < play->view.eye.y) {
for (i = 0; i < end; i++) {
FrameInterpolation_RecordOpenChild(this, i + end);
if (!phi_s5) {
Gfx_SetupDL25_Xlu(play->state.gfxCtx);

Expand All @@ -731,15 +732,16 @@ void func_808DDE9C(Actor* thisx, PlayState* play2) {
temp_f2 = this->unk_14C[1].unk_08 + (func_808DDE74() * 220.0f);

if (!((temp_f20 < -252.0f) && (temp_f20 > -500.0f) && (temp_f2 > 3820.0f) && (temp_f2 < 4150.0f))) {
FrameInterpolation_RecordOpenChild(this, i + end);
Matrix_Translate(temp_f20, temp_f22, temp_f2, MTXMODE_NEW);
temp_f12 = (Rand_ZeroOne() * 0.05f) + 0.05f;
Matrix_Scale(temp_f12, temp_f12, temp_f12, MTXMODE_APPLY);

gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffShockwaveDL);
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}
}

Expand Down

0 comments on commit a94aade

Please sign in to comment.