frame interp: e_s1 & e_yg

This commit is contained in:
Pheenoh
2026-05-08 21:15:52 -06:00
parent 71c892368d
commit 06c77a6818
4 changed files with 104 additions and 1 deletions
+9
View File
@@ -81,6 +81,15 @@ public:
/* 0x306D */ u8 field_0x306D[0x307C - 0x306D];
/* 0x307C */ u32 mBodyEffEmtrID;
/* 0x3080 */ u8 mInitHIO;
#if TARGET_PC
static const int HAIR_STRAND_COUNT = 22;
static const int HAIR_SEGMENT_COUNT = 16;
cXyz mHairInterpPrev[HAIR_STRAND_COUNT * HAIR_SEGMENT_COUNT];
cXyz mHairInterpCurr[HAIR_STRAND_COUNT * HAIR_SEGMENT_COUNT];
bool mHairInterpPrevValid;
bool mHairInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(e_s1_class) == 0x3084);
+9
View File
@@ -63,6 +63,15 @@ public:
/* 0x0BB4 */ yg_ke_s mYgKes[13];
/* 0x1880 */ mDoExt_3DlineMat0_c mLineMat;
/* 0x189C */ u8 mIsFirstSpawn;
#if TARGET_PC
static const int TENTACLE_STRAND_COUNT = 13;
static const int TENTACLE_SEGMENT_COUNT = 10;
cXyz mTentacleInterpPrev[TENTACLE_STRAND_COUNT * TENTACLE_SEGMENT_COUNT];
cXyz mTentacleInterpCurr[TENTACLE_STRAND_COUNT * TENTACLE_SEGMENT_COUNT];
bool mTentacleInterpPrevValid;
bool mTentacleInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(e_yg_class) == 0x18a0);
+42
View File
@@ -14,6 +14,8 @@
#include "d/d_s_play.h"
#include "f_op/f_op_actor_enemy.h"
#include "f_op/f_op_camera_mng.h"
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
#include <cstring>
class daE_S1_HIO_c {
@@ -99,6 +101,25 @@ static void anm_init(e_s1_class* i_this, int i_resNo, f32 i_morf, u8 i_attr, f32
i_this->mAnm = i_resNo;
}
#if TARGET_PC
static void daE_S1_interp_callback(bool isSimFrame, void* pUserWork) {
e_s1_class* i_this = (e_s1_class*)pUserWork;
if (!i_this->mHairInterpPrevValid || !i_this->mHairInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
for (int s = 0; s < e_s1_class::HAIR_STRAND_COUNT; s++) {
cXyz* dst = i_this->mLineMat.getPos(s);
for (int i = 0; i < e_s1_class::HAIR_SEGMENT_COUNT; i++) {
int idx = s * e_s1_class::HAIR_SEGMENT_COUNT + i;
const cXyz& p0 = i_this->mHairInterpPrev[idx];
const cXyz& p1 = i_this->mHairInterpCurr[idx];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
}
#endif
static int daE_S1_Draw(e_s1_class* i_this) {
if (i_this->field_0x306c != 0) {
return 1;
@@ -132,6 +153,22 @@ static int daE_S1_Draw(e_s1_class* i_this) {
i_this->mLineMat.update(16, line_color, &i_this->tevStr);
dComIfGd_set3DlineMatDark(&i_this->mLineMat);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mHairInterpCurrValid) {
memcpy(i_this->mHairInterpPrev, i_this->mHairInterpCurr, sizeof(i_this->mHairInterpCurr));
i_this->mHairInterpPrevValid = true;
}
for (int s = 0; s < e_s1_class::HAIR_STRAND_COUNT; s++) {
cXyz* src = i_this->mLineMat.getPos(s);
memcpy(&i_this->mHairInterpCurr[s * e_s1_class::HAIR_SEGMENT_COUNT], src,
e_s1_class::HAIR_SEGMENT_COUNT * sizeof(cXyz));
}
i_this->mHairInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&daE_S1_interp_callback, i_this);
}
#endif
dComIfGd_setList();
return 1;
}
@@ -2149,6 +2186,11 @@ static int daE_S1_Create(fopAc_ac_c* i_this) {
return cPhs_ERROR_e;
}
#if TARGET_PC
a_this->mHairInterpPrevValid = false;
a_this->mHairInterpCurrValid = false;
#endif
OS_REPORT("//////////////E_S1 SET 2 !!\n");
if (path_no != 0xFF) {
+44 -1
View File
@@ -10,6 +10,8 @@
#include "f_op/f_op_kankyo_mng.h"
#include "d/actor/d_a_obj_carry.h"
#include "Z2AudioLib/Z2Instances.h"
#include "dusk/frame_interpolation.h"
#include "dusk/settings.h"
#include "f_op/f_op_actor_enemy.h"
enum E_yg_RES_File_ID {
@@ -134,7 +136,26 @@ static BOOL pl_check(e_yg_class* i_this, f32 i_dist) {
return FALSE;
}
static int daE_YG_Draw(e_yg_class* i_this) {
#if TARGET_PC
static void daE_YG_interp_callback(bool isSimFrame, void* pUserWork) {
e_yg_class* i_this = (e_yg_class*)pUserWork;
if (!i_this->mTentacleInterpPrevValid || !i_this->mTentacleInterpCurrValid) {
return;
}
const f32 alpha = dusk::frame_interp::get_interpolation_step();
for (int s = 0; s < e_yg_class::TENTACLE_STRAND_COUNT; s++) {
cXyz* dst = i_this->mLineMat.getPos(s);
for (int i = 0; i < e_yg_class::TENTACLE_SEGMENT_COUNT; i++) {
int idx = s * e_yg_class::TENTACLE_SEGMENT_COUNT + i;
const cXyz& p0 = i_this->mTentacleInterpPrev[idx];
const cXyz& p1 = i_this->mTentacleInterpCurr[idx];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
}
#endif
static int daE_YG_Draw(e_yg_class* i_this) {
if (i_this->mDispFlag) {
return 1;
}
@@ -160,6 +181,23 @@ static int daE_YG_Draw(e_yg_class* i_this) {
color.a = 0xFF;
i_this->mLineMat.update(10, color, &actor->tevStr);
dComIfGd_set3DlineMatDark(&i_this->mLineMat);
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
if (i_this->mTentacleInterpCurrValid) {
memcpy(i_this->mTentacleInterpPrev, i_this->mTentacleInterpCurr, sizeof(i_this->mTentacleInterpCurr));
i_this->mTentacleInterpPrevValid = true;
}
for (int s = 0; s < e_yg_class::TENTACLE_STRAND_COUNT; s++) {
cXyz* src = i_this->mLineMat.getPos(s);
memcpy(&i_this->mTentacleInterpCurr[s * e_yg_class::TENTACLE_SEGMENT_COUNT], src,
e_yg_class::TENTACLE_SEGMENT_COUNT * sizeof(cXyz));
}
i_this->mTentacleInterpCurrValid = true;
dusk::frame_interp::add_interpolation_callback(&daE_YG_interp_callback, i_this);
}
#endif
dComIfGd_setList();
return 1;
@@ -1378,6 +1416,11 @@ static cPhs_Step daE_YG_Create(fopAc_ac_c* actor) {
return cPhs_ERROR_e;
}
#if TARGET_PC
i_this->mTentacleInterpPrevValid = false;
i_this->mTentacleInterpCurrValid = false;
#endif
if (!hio_set) {
i_this->mIsFirstSpawn = 1;
hio_set = true;