Refactor chain and line interpolation, revert portion of last PR (#2397)

* Consolidate chain interpolation

* 3D lines interpolate themselves

* Revert d_kankyo_rain camera changes
This commit is contained in:
Irastris
2026-09-06 19:14:00 -04:00
committed by GitHub
parent d67871181d
commit 83f50329d8
45 changed files with 581 additions and 867 deletions
+2
View File
@@ -1462,7 +1462,9 @@ set(DUSK_FILES
src/dusk/imgui/ImGuiStateShare.hpp
src/dusk/imgui/ImGuiStubLog.cpp
src/dusk/interp/camera.cpp
src/dusk/interp/dual_buffer.cpp
src/dusk/interp/frame_interpolation.cpp
src/dusk/interp/line.cpp
src/dusk/io.cpp
src/dusk/iso_validate.cpp
src/dusk/language.cpp
-23
View File
@@ -4556,29 +4556,6 @@ public:
bool checkAimContext();
bool checkAimInputContext();
void onIronBallChainInterpCallback();
static const int IRON_BALL_CHAIN_COUNT = 102;
cXyz mIBChainInterpPrevPos[IRON_BALL_CHAIN_COUNT];
cXyz mIBChainInterpCurrPos[IRON_BALL_CHAIN_COUNT];
csXyz mIBChainInterpPrevAngle[IRON_BALL_CHAIN_COUNT];
csXyz mIBChainInterpCurrAngle[IRON_BALL_CHAIN_COUNT];
cXyz mIBChainInterpPrevHandRoot;
cXyz mIBChainInterpCurrHandRoot;
bool mIBChainInterpPrevValid;
bool mIBChainInterpCurrValid;
cXyz mHsChainInterpPrevTop;
cXyz mHsChainInterpCurrTop;
cXyz mHsChainInterpPrevRoot;
cXyz mHsChainInterpCurrRoot;
cXyz mHsChainInterpPrevSubRoot;
cXyz mHsChainInterpCurrSubRoot;
cXyz mHsChainInterpPrevSubTop;
cXyz mHsChainInterpCurrSubTop;
bool mHsChainInterpPrevValid;
bool mHsChainInterpCurrValid;
bool mIsRollstab = false;
void* mAnmBuffers[3] = {};
#endif
-6
View File
@@ -189,12 +189,6 @@ public:
/* 0x2740 */ u8 field_0x2740;
/* 0x2744 */ dMsgFlow_c mMsgFlow;
#if TARGET_PC
cXyz mReinsInterpPrev[2][16];
cXyz mReinsInterpCurr[2][16];
cXyz mReinsTexInterpPrev[2];
cXyz mReinsTexInterpCurr[2];
bool mReinsInterpPrevValid;
bool mReinsInterpCurrValid;
s8 mDemoCamSyncTicks;
#endif
};
-6
View File
@@ -80,12 +80,6 @@ public:
/* 0x125C */ u32 field_0x125c;
/* 0x1260 */ u8 field_0x1260[0x126C - 0x1260];
/* 0x126C */ u8 HIOInit;
#if TARGET_PC
cXyz mStalkLineInterpPrev[12];
cXyz mStalkLineInterpCurr[12];
bool mStalkLineInterpPrevValid;
bool mStalkLineInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(e_db_class) == 0x1270);
-6
View File
@@ -73,12 +73,6 @@ public:
/* 0x124C */ f32 field_0x124c;
/* 0x1250 */ u8 field_0x1250[0x1264 - 0x1250];
/* 0x1264 */ u8 HIOInit;
#if TARGET_PC
cXyz mStalkLineInterpPrev[12];
cXyz mStalkLineInterpCurr[12];
bool mStalkLineInterpPrevValid;
bool mStalkLineInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(e_hb_class) == 0x1268);
-6
View File
@@ -44,12 +44,6 @@ public:
/* 0x88C */ u8 field_0x88C[0x8C8 - 0x88C];
/* 0x8C8 */ s8 field_0x8c8;
/* 0x8C9 */ u8 mInitHIO;
#if TARGET_PC
cXyz mRopeInterpPrev[16];
cXyz mRopeInterpCurr[16];
bool mRopeInterpPrevValid;
bool mRopeInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(e_mb_class) == 0x8cc);
-9
View File
@@ -81,15 +81,6 @@ 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);
-6
View File
@@ -221,12 +221,6 @@ public:
/* 0x17E4 */ u8 field_0x17e4[0x17e8 - 0x17e4];
/* 0x17E8 */ f32 ride_speed_max; ///< @brief Speed rate for riding calculations.
#if TARGET_PC
cXyz himo_mat_interp_prev[2][16];
cXyz himo_mat_interp_curr[2][16];
cXyz himo_tex_interp_prev[2];
cXyz himo_tex_interp_curr[2];
bool himo_interp_prev_valid;
bool himo_interp_curr_valid;
s8 demo_cam_sync_ticks;
#endif
};
-6
View File
@@ -74,12 +74,6 @@ public:
/* 0x1250 */ f32 field_0x1250;
/* 0x1254 */ u8 field_0x1254[0x1268 - 0x1254];
/* 0x1268 */ u8 field_0x1268;
#if TARGET_PC
cXyz mLineMatInterpPrev[12];
cXyz mLineMatInterpCurr[12];
bool mLineMatInterpPrevValid;
bool mLineMatInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(e_yd_class) == 0x126c);
-9
View File
@@ -63,15 +63,6 @@ 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);
-6
View File
@@ -77,12 +77,6 @@ public:
/* 0x1260 */ u32 field_0x1260;
/* 0x1260 */ u8 field_0x1264[0x1270 - 0x1264];
/* 0x1270 */ bool mIsHIOOwner;
#if TARGET_PC
cXyz mLineInterpPrev[12];
cXyz mLineInterpCurr[12];
bool mLineInterpPrevValid;
bool mLineInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(e_yh_class) == 0x1274);
-3
View File
@@ -196,9 +196,6 @@ public:
void copyReinPos();
void setReinPosHandSubstance(int);
void setReinPosNormalSubstance();
#if TARGET_PC
void lerpControlPoints(f32 alpha);
#endif
void bgCheck();
bool checkSpecialWallHitSubstance(cXyz const&) const;
void setServiceWaitTimer();
-7
View File
@@ -299,13 +299,6 @@ public:
/* 0x168C */ u8 field_0x168c;
/* 0x168D */ u8 field_0x168d;
/* 0x168E */ u8 HIOInit;
#if TARGET_PC
cXyz mLineInterpPrev[MG_ROD_LURE_LINE_LEN];
cXyz mLineInterpCurr[MG_ROD_LURE_LINE_LEN];
bool mLineInterpPrevValid;
bool mLineInterpCurrValid;
#endif
};
#endif /* D_A_MG_ROD_H */
-12
View File
@@ -31,10 +31,6 @@ public:
csXyz* getAngle() { return field_0x8a4; }
J3DModelData* getModelData() { return mModelData; }
#if TARGET_PC
void onInterpCallback();
#endif
/* 0x568 */ request_of_phase_process_class mPhase;
/* 0x570 */ J3DModelData* mModelData;
/* 0x574 */ daObjFchain_shape_c mShape;
@@ -45,14 +41,6 @@ public:
/* 0x694 */ cXyz field_0x694[22];
/* 0x79C */ cXyz field_0x79c[22];
/* 0x8A4 */ csXyz field_0x8a4[22];
#if TARGET_PC
static const int CHAIN_COUNT = 22;
cXyz mChainInterpPrev[CHAIN_COUNT];
cXyz mChainInterpCurr[CHAIN_COUNT];
bool mChainInterpPrevValid;
bool mChainInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(daObjFchain_c) == 0x928);
-7
View File
@@ -66,13 +66,6 @@ public:
/* 0x2CA7 */ s8 hide_lock;
/* 0x2CA8 */ cXyz field_0x2ca8;
/* 0x2CB4 */ u8 field_0x2cb4;
#if TARGET_PC
Mtx mChainInterpPrev[6][16];
Mtx mChainInterpCurr[6][16];
bool mChainInterpPrevValid;
bool mChainInterpCurrValid;
#endif
};
STATIC_ASSERT(sizeof(obj_keyhole_class) == 0x2CB8);
+1 -8
View File
@@ -26,7 +26,7 @@ public:
int Delete();
#if TARGET_PC
void onInterpCallback();
void onInterpPresentation();
#endif
enum Param_e {
@@ -53,13 +53,6 @@ public:
/* 0x1020 */ dCcD_Cyl mCylinderCollider;
/* 0x115C */ s32 mStopSwingingFrames;
#if TARGET_PC
cXyz mChainInterpPrev[64];
cXyz mChainInterpCurr[64];
bool mChainInterpPrevValid;
bool mChainInterpCurrValid;
#endif
// Number of chain models
u32 getArg0() {
return fopAcM_GetParamBit(this, 0, 6);
+1 -1
View File
@@ -441,7 +441,7 @@ public:
}
#if TARGET_PC
void refresh3DlineMats(const cXyz& eye);
void refresh3DlineMats();
#endif
void peekZdata() { mPeekZ.peekData(); }
+15 -12
View File
@@ -542,10 +542,18 @@ public:
virtual void setMaterial() = 0;
virtual void draw() = 0;
#if TARGET_PC
virtual void refreshGeometryForPresentationEye(const cXyz& eye) {}
virtual void captureInterpPoints() {}
virtual void refreshGeometryForPresentation() {}
#endif
/* 0x4 */ mDoExt_3DlineMat_c* field_0x4;
#if TARGET_PC
protected:
u8 mInterpKind;
f32 mInterpWidth;
u16 mInterpTaper;
#endif
};
class mDoExt_3DlineMat0_c : public mDoExt_3DlineMat_c {
@@ -567,6 +575,10 @@ public:
virtual int getMaterialID() { return 0; }
virtual void setMaterial();
virtual void draw();
#if TARGET_PC
void captureInterpPoints() override;
void refreshGeometryForPresentation() override;
#endif
cXyz* getPos(int param_0) { return field_0x18[param_0].field_0x0; }
f32* getSize(int param_0) { return field_0x18[param_0].field_0x4; }
@@ -585,18 +597,14 @@ class dKy_tevstr_c;
class mDoExt_3DlineMat1_c : public mDoExt_3DlineMat_c {
public:
int init(u16, u16, ResTIMG*, int);
#if TARGET_PC
void update(int, GXColor&, dKy_tevstr_c*, const cXyz* presentationEye = nullptr);
void update(int, f32, GXColor&, u16, dKy_tevstr_c*, const cXyz* presentationEye = nullptr);
#else
void update(int, GXColor&, dKy_tevstr_c*);
void update(int, f32, GXColor&, u16, dKy_tevstr_c*);
#endif
int getMaterialID() { return 1; }
void setMaterial();
void draw();
#if TARGET_PC
void refreshGeometryForPresentationEye(const cXyz& eye) override;
void captureInterpPoints() override;
void refreshGeometryForPresentation() override;
#endif
cXyz* getPos(int i_idx) { return mpLines[i_idx].field_0x0; }
@@ -611,11 +619,6 @@ private:
/* 0x34 */ u16 field_0x34;
/* 0x36 */ u8 mIsDrawn;
/* 0x38 */ mDoExt_3Dline_c* mpLines;
#if TARGET_PC
u8 mInterpLineKind;
f32 mInterpLineF;
u16 mInterpLineU16;
#endif
};
class mDoExt_3DlineMat2_c : public mDoExt_3DlineMat1_c {
+32 -32
View File
@@ -53,13 +53,25 @@
#if TARGET_PC
#include "dusk/action_bindings.h"
#include "dusk/interp/dual_buffer.h"
#include "dusk/interp/frame_interpolation.h"
#include "dusk/settings.h"
#include "helpers/string.hpp"
#include "res/Object/Alink.h"
#include <cstring>
#include <helpers/string.hpp>
static const int IRON_BALL_CHAIN_COUNT = 102;
static const int HS_CHAIN_ANCHOR_COUNT = 4;
namespace {
struct AlinkInterp {
dusk::interp::DualBuffer<cXyz, IRON_BALL_CHAIN_COUNT> ib_pos;
dusk::interp::DualBuffer<csXyz, IRON_BALL_CHAIN_COUNT> ib_angle;
dusk::interp::DualBuffer<cXyz, 1> ib_hand;
cXyz hs_draw[HS_CHAIN_ANCHOR_COUNT];
dusk::interp::DualBuffer<cXyz, HS_CHAIN_ANCHOR_COUNT> hs_chain{hs_draw};
};
} // namespace
#endif
static int daAlink_Create(fopAc_ac_c* i_this);
@@ -14818,10 +14830,13 @@ void daAlink_c::deleteEquipItem(BOOL i_isPlaySound, BOOL i_isDeleteKantera) {
mIronBallChainAngle = NULL;
field_0x3848 = NULL;
#if TARGET_PC
mIBChainInterpPrevValid = false;
mIBChainInterpCurrValid = false;
mHsChainInterpPrevValid = false;
mHsChainInterpCurrValid = false;
{
auto& interp = dusk::interp::get<AlinkInterp>(this);
interp.ib_pos.reset();
interp.ib_angle.reset();
interp.ib_hand.reset();
interp.hs_chain.reset();
}
#endif
field_0x0774 = NULL;
field_0x0778 = NULL;
@@ -19795,35 +19810,20 @@ int daAlink_c::draw() {
#if TARGET_PC
if (dusk::interp::is_enabled()) {
auto& interp = dusk::interp::get<AlinkInterp>(this);
if (mEquipItem == dItemNo_IRONBALL_e &&
mIronBallChainPos != NULL && mIronBallChainAngle != NULL)
{
if (mIBChainInterpCurrValid) {
memcpy(mIBChainInterpPrevPos, mIBChainInterpCurrPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpPrevAngle, mIBChainInterpCurrAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpPrevHandRoot = mIBChainInterpCurrHandRoot;
mIBChainInterpPrevValid = true;
}
memcpy(mIBChainInterpCurrPos, mIronBallChainPos, IRON_BALL_CHAIN_COUNT * sizeof(cXyz));
memcpy(mIBChainInterpCurrAngle, mIronBallChainAngle, IRON_BALL_CHAIN_COUNT * sizeof(csXyz));
mIBChainInterpCurrHandRoot = mHookshotTopPos;
mIBChainInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&ironBallChainInterpCallback, this);
interp.ib_pos.writeback(mIronBallChainPos, IRON_BALL_CHAIN_COUNT);
interp.ib_angle.writeback(mIronBallChainAngle, IRON_BALL_CHAIN_COUNT);
interp.ib_hand.writeback(&mHookshotTopPos, 1);
} else {
if (mHsChainInterpCurrValid) {
mHsChainInterpPrevTop = mHsChainInterpCurrTop;
mHsChainInterpPrevRoot = mHsChainInterpCurrRoot;
mHsChainInterpPrevSubRoot = mHsChainInterpCurrSubRoot;
mHsChainInterpPrevSubTop = mHsChainInterpCurrSubTop;
mHsChainInterpPrevValid = true;
}
mHsChainInterpCurrTop = mHookshotTopPos;
mHsChainInterpCurrRoot = mHeldItemRootPos;
mHsChainInterpCurrSubRoot = field_0x3810;
mHsChainInterpCurrSubTop = mIronBallBgChkPos;
mHsChainInterpCurrValid = true;
cXyz hsAnchors[HS_CHAIN_ANCHOR_COUNT];
hsAnchors[0] = mHookshotTopPos;
hsAnchors[1] = mHeldItemRootPos;
hsAnchors[2] = field_0x3810;
hsAnchors[3] = mIronBallBgChkPos;
interp.hs_chain.capture_and_schedule(hsAnchors, HS_CHAIN_ANCHOR_COUNT);
}
}
#endif
+9 -33
View File
@@ -10,6 +10,7 @@
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#if TARGET_PC
#include "dusk/interp/dual_buffer.h"
#include "dusk/interp/frame_interpolation.h"
#include "dusk/settings.h"
@@ -137,15 +138,15 @@ void daAlink_c::hsChainShape_c::draw() {
} else {
#if TARGET_PC
cXyz hsInterpTop, hsInterpRoot, hsInterpSubRoot, hsInterpSubTop;
if (dusk::interp::is_enabled() && alink->mHsChainInterpPrevValid && alink->mHsChainInterpCurrValid) {
const f32 alpha = dusk::interp::get_interpolation_step();
hsInterpTop = alink->mHsChainInterpPrevTop + (alink->mHsChainInterpCurrTop - alink->mHsChainInterpPrevTop) * alpha;
hsInterpRoot = alink->mHsChainInterpPrevRoot + (alink->mHsChainInterpCurrRoot - alink->mHsChainInterpPrevRoot) * alpha;
hsInterpSubRoot = alink->mHsChainInterpPrevSubRoot + (alink->mHsChainInterpCurrSubRoot - alink->mHsChainInterpPrevSubRoot) * alpha;
hsInterpSubTop = alink->mHsChainInterpPrevSubTop + (alink->mHsChainInterpCurrSubTop - alink->mHsChainInterpPrevSubTop) * alpha;
auto& hsInterp = dusk::interp::get<AlinkInterp>(alink);
if (dusk::interp::is_enabled() && hsInterp.hs_chain.ready()) {
hsInterpTop = hsInterp.hs_draw[0];
hsInterpRoot = hsInterp.hs_draw[1];
hsInterpSubRoot = hsInterp.hs_draw[2];
hsInterpSubTop = hsInterp.hs_draw[3];
} else {
hsInterpTop = alink->getHsChainTopPos();
hsInterpRoot = alink->getHsChainRootPos();
hsInterpTop = alink->getHsChainTopPos();
hsInterpRoot = alink->getHsChainRootPos();
hsInterpSubRoot = alink->getHsSubChainRootPos();
hsInterpSubTop = alink->getHsSubChainTopPos();
}
@@ -243,31 +244,6 @@ void daAlink_c::hsChainShape_c::draw() {
}
}
#if TARGET_PC
static void ironBallChainInterpCallback(void* pUserWork) {
static_cast<daAlink_c*>(pUserWork)->onIronBallChainInterpCallback();
}
void daAlink_c::onIronBallChainInterpCallback() {
if (!mIBChainInterpPrevValid || !mIBChainInterpCurrValid) {
return;
}
if (mIronBallChainPos == NULL || mIronBallChainAngle == NULL) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
for (int i = 0; i < IRON_BALL_CHAIN_COUNT; i++) {
mIronBallChainPos[i] = mIBChainInterpPrevPos[i] + (mIBChainInterpCurrPos[i] - mIBChainInterpPrevPos[i]) * alpha;
mIronBallChainAngle[i].x = mIBChainInterpPrevAngle[i].x + (s16)((s16)(mIBChainInterpCurrAngle[i].x - mIBChainInterpPrevAngle[i].x) * alpha);
mIronBallChainAngle[i].y = mIBChainInterpPrevAngle[i].y + (s16)((s16)(mIBChainInterpCurrAngle[i].y - mIBChainInterpPrevAngle[i].y) * alpha);
mIronBallChainAngle[i].z = mIBChainInterpPrevAngle[i].z + (s16)((s16)(mIBChainInterpCurrAngle[i].z - mIBChainInterpPrevAngle[i].z) * alpha);
}
mHookshotTopPos = mIBChainInterpPrevHandRoot + (mIBChainInterpCurrHandRoot - mIBChainInterpPrevHandRoot) * alpha;
}
#endif
void daAlink_c::hookshotAtHitCallBack(dCcD_GObjInf* i_atObjInf, fopAc_ac_c* i_tgActor,
dCcD_GObjInf* i_tgObjInf) {
if (i_tgActor != NULL && fopAcM_IsActor(i_tgActor) && !i_tgObjInf->ChkTgHookshotThrough()) {
-39
View File
@@ -285,30 +285,6 @@ static int h_nodeCallBack(J3DJoint* i_joint, int param_2) {
return 1;
}
#if TARGET_PC
static void b_gnd_rein_interp_callback(void* pUserWork) {
b_gnd_class* i_this = (b_gnd_class*)pUserWork;
if (!i_this->mReinsInterpPrevValid || !i_this->mReinsInterpCurrValid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
for (int r = 0; r < 2; r++) {
cXyz* dst = i_this->mHorseReins[r].getPos(0);
for (int i = 0; i < 16; i++) {
const cXyz& p0 = i_this->mReinsInterpPrev[r][i];
const cXyz& p1 = i_this->mReinsInterpCurr[r][i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
cXyz* dst = i_this->field_0x21e8.getPos(0);
for (int i = 0; i < 2; i++) {
const cXyz& p0 = i_this->mReinsTexInterpPrev[i];
const cXyz& p1 = i_this->mReinsTexInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static int daB_GND_Draw(b_gnd_class* i_this) {
fopAc_ac_c* a_this = (fopAc_ac_c*)i_this;
@@ -396,21 +372,6 @@ static int daB_GND_Draw(b_gnd_class* i_this) {
i_this->field_0x21e8.update(2, l_color, &a_this->tevStr);
dComIfGd_set3DlineMat(&i_this->field_0x21e8);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->mReinsInterpCurrValid) {
memcpy(i_this->mReinsInterpPrev, i_this->mReinsInterpCurr, sizeof(i_this->mReinsInterpCurr));
memcpy(i_this->mReinsTexInterpPrev, i_this->mReinsTexInterpCurr, sizeof(i_this->mReinsTexInterpCurr));
i_this->mReinsInterpPrevValid = true;
}
for (int r = 0; r < 2; r++) {
memcpy(i_this->mReinsInterpCurr[r], i_this->mHorseReins[r].getPos(0), 16 * sizeof(cXyz));
}
memcpy(i_this->mReinsTexInterpCurr, i_this->field_0x21e8.getPos(0), 2 * sizeof(cXyz));
i_this->mReinsInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&b_gnd_rein_interp_callback, i_this);
}
#endif
}
return 1;
-31
View File
@@ -10,10 +10,6 @@
#include "f_op/f_op_kankyo_mng.h"
#include "f_op/f_op_actor_enemy.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
class daE_DB_HIO_c : public JORReflexible {
public:
daE_DB_HIO_c();
@@ -70,22 +66,6 @@ static BOOL leaf_anm_init(e_db_class* i_this, int i_anm, f32 i_morf, u8 i_mode,
return FALSE;
}
#if TARGET_PC
static void daE_DB_interp_callback(void* pUserWork) {
e_db_class* i_this = (e_db_class*)pUserWork;
if (!i_this->mStalkLineInterpPrevValid || !i_this->mStalkLineInterpCurrValid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
cXyz* dst = i_this->stalkLine.getPos(0);
for (int i = 0; i < 12; i++) {
const cXyz& p0 = i_this->mStalkLineInterpPrev[i];
const cXyz& p1 = i_this->mStalkLineInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static int daE_DB_Draw(e_db_class* i_this) {
fopAc_ac_c* actor = &i_this->enemy;
@@ -115,17 +95,6 @@ static int daE_DB_Draw(e_db_class* i_this) {
static GXColor l_color = {0x14, 0x0F, 0x00, 0xFF};
i_this->stalkLine.update(12, l_color, &actor->tevStr);
dComIfGd_set3DlineMat(&i_this->stalkLine);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->mStalkLineInterpCurrValid) {
memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr));
i_this->mStalkLineInterpPrevValid = true;
}
memcpy(i_this->mStalkLineInterpCurr, i_this->stalkLine.getPos(0), 12 * sizeof(cXyz));
i_this->mStalkLineInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&daE_DB_interp_callback, i_this);
}
#endif
for (int i = 1; i < 11; i++) {
if (i_this->thornModel[i] != NULL) {
-31
View File
@@ -9,10 +9,6 @@
#include "d/actor/d_a_e_hb_leaf.h"
#include "f_op/f_op_actor_enemy.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
enum daE_HB_ACTION {
ACTION_STAY,
ACTION_APPEAR,
@@ -68,22 +64,6 @@ static BOOL leaf_anm_init(e_hb_class* i_this, int i_anm, f32 i_morf, u8 i_mode,
return FALSE;
}
#if TARGET_PC
static void daE_HB_interp_callback(void* pUserWork) {
e_hb_class* i_this = (e_hb_class*)pUserWork;
if (!i_this->mStalkLineInterpPrevValid || !i_this->mStalkLineInterpCurrValid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
cXyz* dst = i_this->stalkLine.getPos(0);
for (int i = 0; i < 12; i++) {
const cXyz& p0 = i_this->mStalkLineInterpPrev[i];
const cXyz& p1 = i_this->mStalkLineInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static int daE_HB_Draw(e_hb_class* i_this) {
fopAc_ac_c* actor = &i_this->enemy;
@@ -102,17 +82,6 @@ static int daE_HB_Draw(e_hb_class* i_this) {
static GXColor l_color = {0x14, 0x0F, 0x00, 0xFF};
i_this->stalkLine.update(12, l_color, &actor->tevStr);
dComIfGd_set3DlineMat(&i_this->stalkLine);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->mStalkLineInterpCurrValid) {
memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr));
i_this->mStalkLineInterpPrevValid = true;
}
memcpy(i_this->mStalkLineInterpCurr, i_this->stalkLine.getPos(0), 12 * sizeof(cXyz));
i_this->mStalkLineInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&daE_HB_interp_callback, i_this);
}
#endif
for (int i = 1; i < 11; i++) {
if (i_this->thornModel[i] != NULL) {
-31
View File
@@ -13,10 +13,6 @@
#include "c/c_damagereaction.h"
#include "Z2AudioLib/Z2Instances.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
#define ACTION_STANDBY 0
#define ACTION_WALK1 1
#define ACTION_MOVE 2
@@ -67,22 +63,6 @@ static void anm_init(e_mb_class* i_this, int i_anmID, f32 i_morf, u8 i_attr, f32
i_this->mAnm = i_anmID;
}
#if TARGET_PC
static void e_mb_rope_interp_callback(void* pUserWork) {
e_mb_class* i_this = (e_mb_class*)pUserWork;
if (!i_this->mRopeInterpPrevValid || !i_this->mRopeInterpCurrValid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
cXyz* dst = i_this->mRopeMat.getPos(0);
for (int i = 0; i < 16; i++) {
const cXyz& p0 = i_this->mRopeInterpPrev[i];
const cXyz& p1 = i_this->mRopeInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static int daE_MB_Draw(e_mb_class* i_this) {
fopAc_ac_c* a_this = (fopAc_ac_c*)i_this;
@@ -106,17 +86,6 @@ static int daE_MB_Draw(e_mb_class* i_this) {
static GXColor l_color = {0x14, 0x0F, 0x00, 0xFF};
i_this->mRopeMat.update(16, l_color, &a_this->tevStr);
dComIfGd_set3DlineMat(&i_this->mRopeMat);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->mRopeInterpCurrValid) {
memcpy(i_this->mRopeInterpPrev, i_this->mRopeInterpCurr, sizeof(i_this->mRopeInterpCurr));
i_this->mRopeInterpPrevValid = true;
}
memcpy(i_this->mRopeInterpCurr, i_this->mRopeMat.getPos(0), 16 * sizeof(cXyz));
i_this->mRopeInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&e_mb_rope_interp_callback, i_this);
}
#endif
return 1;
}
-51
View File
@@ -16,10 +16,6 @@
#include "f_op/f_op_camera_mng.h"
#include <cstring>
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
class daE_S1_HIO_c {
public:
daE_S1_HIO_c();
@@ -103,32 +99,6 @@ 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(void* pUserWork) {
e_s1_class* i_this = (e_s1_class*)pUserWork;
if (!i_this->mHairInterpPrevValid || !i_this->mHairInterpCurrValid) {
return;
}
const f32 alpha = dusk::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;
}
}
GXColor line_color;
line_color.r = JREG_S(0) + 5;
line_color.g = JREG_S(1) + 10;
line_color.b = JREG_S(2) + 10;
line_color.a = 0xFF;
i_this->mLineMat.update(16, line_color, &i_this->tevStr);
}
#endif
static int daE_S1_Draw(e_s1_class* i_this) {
if (i_this->field_0x306c != 0) {
return 1;
@@ -162,22 +132,6 @@ 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::interp::is_enabled()) {
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::interp::add_interpolation_callback(&daE_S1_interp_callback, i_this);
}
#endif
dComIfGd_setList();
return 1;
}
@@ -2195,11 +2149,6 @@ 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) {
+1 -39
View File
@@ -21,6 +21,7 @@
#include <cstring>
#if TARGET_PC
#include "dusk/dusk.h"
#include "dusk/interp/frame_interpolation.h"
#endif
@@ -187,30 +188,6 @@ static bool hio_set;
static daE_WB_HIO_c l_HIO;
#if TARGET_PC
static void e_wb_rein_interp_callback(void* pUserWork) {
e_wb_class* i_this = (e_wb_class*)pUserWork;
if (!i_this->himo_interp_prev_valid || !i_this->himo_interp_curr_valid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
for (int r = 0; r < 2; r++) {
cXyz* dst = i_this->himo_mat[r].getPos(0);
for (int i = 0; i < 16; i++) {
const cXyz& p0 = i_this->himo_mat_interp_prev[r][i];
const cXyz& p1 = i_this->himo_mat_interp_curr[r][i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
cXyz* dst = i_this->himo_tex.getPos(0);
for (int i = 0; i < 2; i++) {
const cXyz& p0 = i_this->himo_tex_interp_prev[i];
const cXyz& p1 = i_this->himo_tex_interp_curr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static void himo_control1(e_wb_class* i_this, cXyz* i_pos, int i_no, s8 param_3) {
fopEn_enemy_c* enemy = &i_this->enemy;
cXyz mae, ato;
@@ -535,21 +512,6 @@ static int daE_WB_Draw(e_wb_class* i_this) {
dComIfGd_set3DlineMat(&i_this->himo_mat[1]);
i_this->himo_tex.update(2, l_color, &actor->tevStr);
dComIfGd_set3DlineMat(&i_this->himo_tex);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->himo_interp_curr_valid) {
memcpy(i_this->himo_mat_interp_prev, i_this->himo_mat_interp_curr, sizeof(i_this->himo_mat_interp_curr));
memcpy(i_this->himo_tex_interp_prev, i_this->himo_tex_interp_curr, sizeof(i_this->himo_tex_interp_curr));
i_this->himo_interp_prev_valid = true;
}
for (int r = 0; r < 2; r++) {
memcpy(i_this->himo_mat_interp_curr[r], i_this->himo_mat[r].getPos(0), 16 * sizeof(cXyz));
}
memcpy(i_this->himo_tex_interp_curr, i_this->himo_tex.getPos(0), 2 * sizeof(cXyz));
i_this->himo_interp_curr_valid = true;
dusk::interp::add_interpolation_callback(&e_wb_rein_interp_callback, i_this);
}
#endif
}
return 1;
-31
View File
@@ -12,10 +12,6 @@
#include "d/d_cc_uty.h"
#include "f_op/f_op_actor_enemy.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
class daE_YD_HIO_c {
public:
daE_YD_HIO_c();
@@ -77,22 +73,6 @@ static s32 leaf_anm_init(e_yd_class* i_this, int param_1, f32 param_2, u8 param_
return false;
}
#if TARGET_PC
static void daE_YD_interp_callback(void* pUserWork) {
e_yd_class* i_this = (e_yd_class*)pUserWork;
if (!i_this->mLineMatInterpPrevValid || !i_this->mLineMatInterpCurrValid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
cXyz* dst = i_this->mLineMat.getPos(0);
for (int i = 0; i < 12; i++) {
const cXyz& p0 = i_this->mLineMatInterpPrev[i];
const cXyz& p1 = i_this->mLineMatInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static s32 daE_YD_Draw(e_yd_class* i_this) {
static GXColor l_color = { 0x14, 0x0F, 0x00, 0xFF };
@@ -106,17 +86,6 @@ static s32 daE_YD_Draw(e_yd_class* i_this) {
i_this->mpMorf->entryDL();
i_this->mLineMat.update(12, l_color, &i_this->actor.tevStr);
dComIfGd_set3DlineMat(&i_this->mLineMat);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->mLineMatInterpCurrValid) {
memcpy(i_this->mLineMatInterpPrev, i_this->mLineMatInterpCurr, sizeof(i_this->mLineMatInterpCurr));
i_this->mLineMatInterpPrevValid = true;
}
memcpy(i_this->mLineMatInterpCurr, i_this->mLineMat.getPos(0), 12 * sizeof(cXyz));
i_this->mLineMatInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&daE_YD_interp_callback, i_this);
}
#endif
for (s32 i = 1; i < 11; i++) {
if (i_this->field_0x77c[i] != 0) {
g_env_light.setLightTevColorType_MAJI(i_this->field_0x77c[i], &i_this->actor.tevStr);
-52
View File
@@ -12,10 +12,6 @@
#include "Z2AudioLib/Z2Instances.h"
#include "f_op/f_op_actor_enemy.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
enum E_yg_RES_File_ID {
/* BCK */
/* 0x04 */ BCK_YG_BITE_DIE = 0x4,
@@ -138,33 +134,6 @@ static BOOL pl_check(e_yg_class* i_this, f32 i_dist) {
return FALSE;
}
#if TARGET_PC
static void daE_YG_interp_callback(void* pUserWork) {
e_yg_class* i_this = (e_yg_class*)pUserWork;
fopAc_ac_c* actor = (fopAc_ac_c*)&i_this->actor;
if (!i_this->mTentacleInterpPrevValid || !i_this->mTentacleInterpCurrValid) {
return;
}
const f32 alpha = dusk::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;
}
}
GXColor color;
color.r = JREG_S(0) + 20;
color.g = JREG_S(1) + 20;
color.b = JREG_S(2) + 20;
color.a = 0xFF;
i_this->mLineMat.update(10, color, &actor->tevStr);
}
#endif
static int daE_YG_Draw(e_yg_class* i_this) {
if (i_this->mDispFlag) {
return 1;
@@ -192,22 +161,6 @@ static int daE_YG_Draw(e_yg_class* i_this) {
i_this->mLineMat.update(10, color, &actor->tevStr);
dComIfGd_set3DlineMatDark(&i_this->mLineMat);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
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::interp::add_interpolation_callback(&daE_YG_interp_callback, i_this);
}
#endif
dComIfGd_setList();
return 1;
@@ -1426,11 +1379,6 @@ 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;
-31
View File
@@ -12,10 +12,6 @@
#include "f_op/f_op_actor_enemy.h"
#include "f_op/f_op_kankyo_mng.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
class daE_YH_HIO_c : public JORReflexible {
public:
daE_YH_HIO_c();
@@ -89,22 +85,6 @@ static BOOL leaf_anm_init(e_yh_class* i_this, int param_2, f32 param_3, u8 param
return FALSE;
}
#if TARGET_PC
static void daE_YH_interp_callback(void* pUserWork) {
e_yh_class* i_this = (e_yh_class*)pUserWork;
if (!i_this->mLineInterpPrevValid || !i_this->mLineInterpCurrValid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
cXyz* dst = i_this->mLine.getPos(0);
for (int i = 0; i < 12; i++) {
const cXyz& p0 = i_this->mLineInterpPrev[i];
const cXyz& p1 = i_this->mLineInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
static int daE_YH_Draw(e_yh_class* i_this) {
fopAc_ac_c* a_this = (fopAc_ac_c*)i_this;
@@ -134,17 +114,6 @@ static int daE_YH_Draw(e_yh_class* i_this) {
i_this->mLine.update(12, l_color, &a_this->tevStr);
dComIfGd_set3DlineMat(&i_this->mLine);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->mLineInterpCurrValid) {
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, sizeof(i_this->mLineInterpCurr));
i_this->mLineInterpPrevValid = true;
}
memcpy(i_this->mLineInterpCurr, i_this->mLine.getPos(0), 12 * sizeof(cXyz));
i_this->mLineInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&daE_YH_interp_callback, i_this);
}
#endif
for (int i = 1; i < 11; i++) {
if (i_this->mModels[i] != NULL) {
-58
View File
@@ -20,22 +20,6 @@
#include <cmath>
#include <cstring>
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
namespace {
// FRAME INTERP NOTE: Sim tick control point snapshots for interpolation
constexpr int kHorseReinSimMax = 75;
cXyz s_horseReinSimPrev[kHorseReinSimMax];
cXyz s_horseReinSimCurr[kHorseReinSimMax];
int s_horseReinSimNumPrev;
int s_horseReinSimNumCurr;
bool s_horseReinSimPrevValid;
bool s_horseReinSimCurrValid;
uint64_t s_horseReinSimRolledSeq;
} // namespace
#endif
#define ANM_HS_BACK_WALK 6
#define ANM_HS_WALK_START 7
#define ANM_HS_EXCITEMENT 8
@@ -3032,24 +3016,6 @@ void daHorse_c::copyReinPos() {
for (i = rein->field_0x8[0] - 1; i >= 0; i--, pos_p++) {
*pos_p = rein->field_0x0[0][i];
}
#if TARGET_PC
if (field_0x1204 > 0) {
const uint64_t simSeq = dusk::interp::sim_tick_seq();
if (simSeq != s_horseReinSimRolledSeq) {
s_horseReinSimRolledSeq = simSeq;
if (s_horseReinSimCurrValid && s_horseReinSimNumCurr > 0) {
memcpy(s_horseReinSimPrev, s_horseReinSimCurr, s_horseReinSimNumCurr * sizeof(cXyz));
s_horseReinSimNumPrev = s_horseReinSimNumCurr;
s_horseReinSimPrevValid = true;
}
}
memcpy(s_horseReinSimCurr, m_reinLine.getPos(0), field_0x1204 * sizeof(cXyz));
s_horseReinSimNumCurr = field_0x1204;
s_horseReinSimCurrValid = true;
} else {
s_horseReinSimCurrValid = false;
}
#endif
}
void daHorse_c::setReinPosHandSubstance(int param_0) {
@@ -3161,30 +3127,6 @@ void daHorse_c::setReinPosNormalSubstance() {
copyReinPos();
}
#if TARGET_PC
void daHorse_c::lerpControlPoints(f32 alpha) {
// FRAME INTERP NOTE: Currently only lerping points for Epona's reins. Need a more global solution.
if (!dusk::interp::is_enabled() || !s_horseReinSimPrevValid || !s_horseReinSimCurrValid) {
return;
}
const int nCurr = s_horseReinSimNumCurr;
const int nPrev = s_horseReinSimNumPrev;
if (nCurr <= 0) {
return;
}
int n = nPrev < nCurr ? nPrev : nCurr;
if (n <= 0 || n > kHorseReinSimMax) {
return;
}
cXyz* dst = m_reinLine.getPos(0);
for (int i = 0; i < n; i++) {
const cXyz& p0 = s_horseReinSimPrev[i];
const cXyz& p1 = s_horseReinSimCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
void daHorse_c::bgCheck() {
if (m_procID != PROC_LARGE_DAMAGE_e) {
static DUSK_CONSTEXPR cXyz localCenterPos(0.0f, 100.0f, 0.0f);
-49
View File
@@ -26,7 +26,6 @@
#include <cstring>
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#include "dusk/mods/item.hpp"
#include "dusk/settings.h"
#include "dusk/version.hpp"
@@ -183,25 +182,6 @@ static int Worm_nodeCallBack(J3DJoint* i_joint, int param_1) {
return 1;
}
#if TARGET_PC
static void dmg_rod_interp_callback(void* pUserWork) {
dmg_rod_class* i_this = (dmg_rod_class*)pUserWork;
if (!i_this->mLineInterpPrevValid || !i_this->mLineInterpCurrValid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
const int count = i_this->kind == MG_ROD_KIND_LURE ? MG_ROD_LURE_LINE_LEN : MG_ROD_UKI_LINE_LEN;
cXyz* dst = i_this->linemat.getPos(0);
for (int i = 0; i < count; i++) {
const cXyz& p0 = i_this->mLineInterpPrev[i];
const cXyz& p1 = i_this->mLineInterpCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
static GXColor l_color = {0xFF, 0xFF, 0x96, 0xFF};
i_this->linemat.update(count, l_color, &i_this->actor.tevStr);
}
#endif
static int dmg_rod_Draw(dmg_rod_class* i_this) {
int unused;
fopAc_ac_c* actor = &i_this->actor;
@@ -242,18 +222,6 @@ static int dmg_rod_Draw(dmg_rod_class* i_this) {
i_this->linemat.update(MG_ROD_LURE_LINE_LEN, l_color, &i_this->actor.tevStr);
dComIfGd_set3DlineMat(&i_this->linemat);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->mLineInterpCurrValid) {
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, MG_ROD_LURE_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpPrevValid = true;
}
memcpy(i_this->mLineInterpCurr, i_this->linemat.getPos(0), MG_ROD_LURE_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&dmg_rod_interp_callback, i_this);
}
#endif
model = i_this->rod_modelMorf->getModel();
g_env_light.setLightTevColorType_MAJI(model, &i_this->actor.tevStr);
i_this->rod_modelMorf->entryDL();
@@ -278,18 +246,6 @@ static int dmg_rod_Draw(dmg_rod_class* i_this) {
i_this->linemat.update(MG_ROD_UKI_LINE_LEN, l_color, &i_this->actor.tevStr);
dComIfGd_set3DlineMat(&i_this->linemat);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->mLineInterpCurrValid) {
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, MG_ROD_UKI_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpPrevValid = true;
}
memcpy(i_this->mLineInterpCurr, i_this->linemat.getPos(0), MG_ROD_UKI_LINE_LEN * sizeof(cXyz));
i_this->mLineInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&dmg_rod_interp_callback, i_this);
}
#endif
for (int i = 0; i < 15; i++) {
g_env_light.setLightTevColorType_MAJI(i_this->rod_uki_model[i], &actor->tevStr);
mDoExt_modelUpdateDL(i_this->rod_uki_model[i]);
@@ -6481,11 +6437,6 @@ static int dmg_rod_Create(fopAc_ac_c* i_this) {
return cPhs_ERROR_e;
}
#if TARGET_PC
rod->mLineInterpPrevValid = false;
rod->mLineInterpCurrValid = false;
#endif
OS_REPORT("//////////////MG_ROD SET 2 !!\n");
if (!hio_set) {
rod->HIOInit = TRUE;
+5 -37
View File
@@ -13,7 +13,10 @@
#include <cstring>
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#include "dusk/interp/dual_buffer.h"
static const int CHAIN_COUNT = 22;
typedef dusk::interp::DualBuffer<cXyz, CHAIN_COUNT> ChainInterp;
#endif
static char const l_arcName[] = "Fchain";
@@ -69,10 +72,6 @@ int daObjFchain_c::create() {
local_48++;
}
rv = cPhs_COMPLEATE_e;
#if TARGET_PC
mChainInterpPrevValid = false;
mChainInterpCurrValid = false;
#endif
break;
}
return rv;
@@ -297,26 +296,6 @@ void daObjFchain_shape_c::draw() {
}
}
#if TARGET_PC
static void fchain_interp_callback(void* pUserWork) {
static_cast<daObjFchain_c*>(pUserWork)->onInterpCallback();
}
void daObjFchain_c::onInterpCallback() {
if (!mChainInterpPrevValid || !mChainInterpCurrValid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
for (int i = 0; i < CHAIN_COUNT; i++) {
const cXyz& p0 = mChainInterpPrev[i];
const cXyz& p1 = mChainInterpCurr[i];
field_0x694[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
int daObjFchain_c::draw() {
if (field_0x584 != 0) {
g_env_light.settingTevStruct(0, &current.pos, &tevStr);
@@ -326,18 +305,7 @@ int daObjFchain_c::draw() {
}
dComIfGd_getOpaListDark()->entryImm(&mShape, 0);
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (mChainInterpCurrValid) {
memcpy(mChainInterpPrev, mChainInterpCurr, sizeof(mChainInterpCurr));
mChainInterpPrevValid = true;
}
memcpy(mChainInterpCurr, field_0x694, sizeof(mChainInterpCurr));
mChainInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&fchain_interp_callback, this);
}
#endif
IF_DUSK(dusk::interp::get<ChainInterp>(this).writeback(field_0x694, CHAIN_COUNT));
}
return 1;
}
-39
View File
@@ -11,10 +11,6 @@
#include "d/actor/d_a_player.h"
#include "Z2AudioLib/Z2Instances.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
daObj_Keyhole_HIO_c::daObj_Keyhole_HIO_c() {
id = -1;
obj_size = 1.0f;
@@ -57,21 +53,6 @@ static int daObj_Keyhole_Draw(obj_keyhole_class* i_this) {
for (int i = 0; i < 6; i++) {
kh_chain_s* chain_s = &i_this->chain_s[i];
for (int j = 0; j < i_this->chain_num; j++) {
#if TARGET_PC
if (dusk::interp::is_enabled() && i_this->mChainInterpPrevValid && i_this->mChainInterpCurrValid) {
const f32 alpha = dusk::interp::get_interpolation_step();
Mtx mtx;
const f32* p0 = (const f32*)i_this->mChainInterpPrev[i][j];
const f32* p1 = (const f32*)i_this->mChainInterpCurr[i][j];
f32* dst = (f32*)mtx;
for (int k = 0; k < 12; k++) {
dst[k] = p0[k] + (p1[k] - p0[k]) * alpha;
}
chain_s->model[j]->setBaseTRMtx(mtx);
g_env_light.setLightTevColorType_MAJI(chain_s->model[j], &actor->tevStr);
mDoExt_modelUpdateDL(chain_s->model[j]);
} else
#endif
dComIfGp_entrySimpleModel(chain_s->model[j], fopAcM_GetRoomNo(actor));
}
}
@@ -389,21 +370,6 @@ static void chain_move(obj_keyhole_class* i_this) {
ANGLE_ADD(sp8, TREG_S(0) + 0x3D00);
}
}
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (i_this->mChainInterpCurrValid) {
memcpy(i_this->mChainInterpPrev, i_this->mChainInterpCurr, sizeof(i_this->mChainInterpCurr));
i_this->mChainInterpPrevValid = true;
}
for (int i = 0; i < 6; i++) {
for (int j = 0; j < i_this->chain_num; j++) {
MTXCopy(i_this->chain_s[i].model[j]->getBaseTRMtx(), i_this->mChainInterpCurr[i][j]);
}
}
i_this->mChainInterpCurrValid = true;
}
#endif
}
static void open(obj_keyhole_class* i_this) {
@@ -784,11 +750,6 @@ static int daObj_Keyhole_Create(fopAc_ac_c* a_this) {
return cPhs_ERROR_e;
}
#if TARGET_PC
i_this->mChainInterpPrevValid = false;
i_this->mChainInterpCurrValid = false;
#endif
OS_REPORT("//////////////OBJ_KEYHOLE SET 2 !!\n");
if (i_this->arg0 == 3) {
+23 -27
View File
@@ -13,7 +13,17 @@
#include "d/d_com_inf_game.h"
#if TARGET_PC
#include "dusk/interp/dual_buffer.h"
#include "dusk/interp/frame_interpolation.h"
static const int CHAIN_INTERP_MAX = 64;
namespace {
struct KLiftInterp {
cXyz draw[CHAIN_INTERP_MAX];
dusk::interp::DualBuffer<cXyz, CHAIN_INTERP_MAX> chain{draw};
};
} // namespace
#endif
struct daObjKLift00_HIO_c : public mDoHIO_entry_c {
@@ -299,11 +309,6 @@ int daObjKLift00_c::Create() {
if(getLock())
mStopSwingingFrames = 5;
#if TARGET_PC
mChainInterpPrevValid = false;
mChainInterpCurrValid = false;
#endif
return 1;
}
@@ -446,23 +451,20 @@ int daObjKLift00_c::Execute(Mtx** i_mtx) {
}
#if TARGET_PC
static void klift00_interp_callback(void* pUserWork) {
static_cast<daObjKLift00_c*>(pUserWork)->onInterpCallback();
static void klift00_interp_post(void* pUserWork) {
static_cast<daObjKLift00_c*>(pUserWork)->onInterpPresentation();
}
void daObjKLift00_c::onInterpCallback() {
if (!mChainInterpPrevValid || !mChainInterpCurrValid) {
return;
}
const f32 alpha = dusk::interp::get_interpolation_step();
cXyz savedPositions[64];
void daObjKLift00_c::onInterpPresentation() {
cXyz savedPositions[CHAIN_INTERP_MAX];
for (int i = 0; i < mNumChains; i++) {
savedPositions[i] = mChainPositions[i].mCurrentPos;
const cXyz& p0 = mChainInterpPrev[i];
const cXyz& p1 = mChainInterpCurr[i];
mChainPositions[i].mCurrentPos = p0 + (p1 - p0) * alpha;
}
auto& interp = dusk::interp::get<KLiftInterp>(this);
for (int i = 0; i < mNumChains; i++) {
mChainPositions[i].mCurrentPos = interp.draw[i];
}
setMtx();
@@ -495,18 +497,12 @@ int daObjKLift00_c::Draw() {
dComIfGd_setList();
#if TARGET_PC
if (dusk::interp::is_enabled()) {
if (mChainInterpCurrValid) {
memcpy(mChainInterpPrev, mChainInterpCurr, mNumChains * sizeof(cXyz));
mChainInterpPrevValid = true;
}
if (dusk::interp::is_enabled() && mNumChains > 0 && mNumChains <= CHAIN_INTERP_MAX) {
cXyz curr[CHAIN_INTERP_MAX];
for (int i = 0; i < mNumChains; i++) {
mChainInterpCurr[i] = mChainPositions[i].mCurrentPos;
curr[i] = mChainPositions[i].mCurrentPos;
}
mChainInterpCurrValid = true;
dusk::interp::add_interpolation_callback(&klift00_interp_callback, this);
dusk::interp::get<KLiftInterp>(this).chain.capture_and_schedule(curr, mNumChains, &klift00_interp_post, this);
}
#endif
+2 -2
View File
@@ -2081,10 +2081,10 @@ void dDlst_list_c::calcWipe() {
}
#if TARGET_PC
void dDlst_list_c::refresh3DlineMats(const cXyz& eye) {
void dDlst_list_c::refresh3DlineMats() {
for (int i = 0; i < 3; i++) {
for (mDoExt_3DlineMat_c* mat = m3DLineMatSortPacket[i].getFirstMat(); mat != NULL; mat = mat->field_0x4) {
mat->refreshGeometryForPresentationEye(eye);
mat->refreshGeometryForPresentation();
}
}
}
+43 -68
View File
@@ -45,48 +45,31 @@ void dKyr_get_vectle_calc(cXyz* i_vecA, cXyz* i_vecB, cXyz* o_out) {
get_vectle_calc(i_vecA, i_vecB, o_out);
}
#if TARGET_PC
static view_class* dKyr_draw_view(camera_class* camera) {
if (dusk::interp::is_presentation_active()) {
if (view_class* view = dComIfGd_getView()) {
return view;
}
}
return &camera->view;
}
#endif
static void dKy_set_eyevect_calc(camera_class* i_camera, Vec* o_out, f32 param_2, f32 param_3) {
cXyz calc;
IF_DUSK(view_class* const view = dKyr_draw_view(i_camera));
get_vectle_calc(DUSK_IF_ELSE(&view->, &i_camera->view.)lookat.eye,
DUSK_IF_ELSE(&view->, &i_camera->view.)lookat.center, &calc);
o_out->x = DUSK_IF_ELSE(view->, i_camera->view.)lookat.eye.x + calc.x * param_2;
o_out->y = (DUSK_IF_ELSE(view->, i_camera->view.)lookat.eye.y + calc.y * param_3) - 200.0f;
o_out->z = DUSK_IF_ELSE(view->, i_camera->view.)lookat.eye.z + calc.z * param_2;
get_vectle_calc(&i_camera->view.lookat.eye, &i_camera->view.lookat.center, &calc);
o_out->x = i_camera->view.lookat.eye.x + calc.x * param_2;
o_out->y = (i_camera->view.lookat.eye.y + calc.y * param_3) - 200.0f;
o_out->z = i_camera->view.lookat.eye.z + calc.z * param_2;
}
void dKy_set_eyevect_calc2(camera_class* i_camera, Vec* o_out, f32 param_2, f32 param_3) {
cXyz calc;
DOUBLE_POS pos;
IF_DUSK(view_class* const view = dKyr_draw_view(i_camera));
pos.x = DUSK_IF_ELSE(view->, i_camera->view.)lookat.center.x -
DUSK_IF_ELSE(view->, i_camera->view.)lookat.eye.x;
pos.x = i_camera->view.lookat.center.x - i_camera->view.lookat.eye.x;
if (param_3 != 0.0f) {
pos.y = DUSK_IF_ELSE(view->, i_camera->view.)lookat.center.y -
DUSK_IF_ELSE(view->, i_camera->view.)lookat.eye.y;
pos.y = i_camera->view.lookat.center.y - i_camera->view.lookat.eye.y;
} else {
pos.y = 0.0f;
}
pos.z = DUSK_IF_ELSE(view->, i_camera->view.)lookat.center.z -
DUSK_IF_ELSE(view->, i_camera->view.)lookat.eye.z;
pos.z = i_camera->view.lookat.center.z - i_camera->view.lookat.eye.z;
vectle_calc(&pos, &calc);
o_out->x = DUSK_IF_ELSE(view->, i_camera->view.)lookat.eye.x + calc.x * param_2;
o_out->y = DUSK_IF_ELSE(view->, i_camera->view.)lookat.eye.y + calc.y * param_3;
o_out->z = DUSK_IF_ELSE(view->, i_camera->view.)lookat.eye.z + calc.z * param_2;
o_out->x = i_camera->view.lookat.eye.x + calc.x * param_2;
o_out->y = i_camera->view.lookat.eye.y + calc.y * param_3;
o_out->z = i_camera->view.lookat.eye.z + calc.z * param_2;
if (param_3 == 0.0f) {
o_out->y = 0.0f;
@@ -148,21 +131,20 @@ static GXTexObj* load_cached_tex(CachedTexObjs<N>& cache, ResTIMG* img, GXTexMap
#if TARGET_PC
static void dKyr_place_sun(camera_class* camera, cXyz* o_sunpos) {
view_class* view = dKyr_draw_view(camera);
cXyz lightDir;
u32 stage_type = dStage_stagInfo_GetSTType(dComIfGp_getStage()->getStagInfo());
if (g_env_light.base_light.mColor.r == 0 && stage_type != ST_ROOM) {
dKyr_get_vectle_calc(&view->lookat.eye, &g_env_light.base_light.mPosition, &lightDir);
dKyr_get_vectle_calc(&camera->view.lookat.eye, &g_env_light.base_light.mPosition,
&lightDir);
} else {
dKyr_get_vectle_calc(&view->lookat.eye, &g_env_light.sun_light_pos, &lightDir);
dKyr_get_vectle_calc(&camera->view.lookat.eye, &g_env_light.sun_light_pos, &lightDir);
}
o_sunpos->x = view->lookat.eye.x + 8000.0f * lightDir.x;
o_sunpos->y = view->lookat.eye.y + 8000.0f * lightDir.y;
o_sunpos->z = view->lookat.eye.z + 8000.0f * lightDir.z;
o_sunpos->x = camera->view.lookat.eye.x + 8000.0f * lightDir.x;
o_sunpos->y = camera->view.lookat.eye.y + 8000.0f * lightDir.y;
o_sunpos->z = camera->view.lookat.eye.z + 8000.0f * lightDir.z;
}
static void dKyr_place_lenzflare(camera_class* camera, cXyz* sunpos, cXyz* o_positions) {
view_class* view = dKyr_draw_view(camera);
cXyz eyeVect;
cXyz sunDirSmth;
cXyz camFwd;
@@ -172,7 +154,7 @@ static void dKyr_place_lenzflare(camera_class* camera, cXyz* sunpos, cXyz* o_pos
o_positions[0] = *sunpos;
o_positions[1] = *sunpos;
dKyr_get_vectle_calc(&view->lookat.eye, &view->lookat.center, &camFwd);
dKyr_get_vectle_calc(&camera->view.lookat.eye, &camera->view.lookat.center, &camFwd);
for (int i = 2; i < 8; i++) {
if (i == 2) {
@@ -2158,17 +2140,16 @@ static void dKyr_draw_rev_moon(Mtx drawMtx, u8** tex) {
dKankyo_sun_Packet* sun_packet = g_env_light.mpSunPacket;
dKankyo_sunlenz_Packet* lenz_packet = g_env_light.mpSunLenzPacket;
camera_class* camera = (camera_class*)dComIfGp_getCamera(0);
IF_DUSK(view_class* const view = dKyr_draw_view(camera));
cXyz pos[4];
u16 date = dComIfGs_getDate();
cXyz sp60 = DUSK_IF_ELSE(view->, camera->view.)lookat.eye + g_env_light.moon_pos;
sp60.y = DUSK_IF_ELSE(view->, camera->view.)lookat.eye.y - g_env_light.moon_pos.y;
cXyz sp60 = camera->view.lookat.eye + g_env_light.moon_pos;
sp60.y = camera->view.lookat.eye.y - g_env_light.moon_pos.y;
cXyz moon_pos;
moon_pos.x = sp60.x - DUSK_IF_ELSE(view->, camera->view.)lookat.eye.x;
moon_pos.y = sp60.y - DUSK_IF_ELSE(view->, camera->view.)lookat.eye.y;
moon_pos.z = sp60.z - DUSK_IF_ELSE(view->, camera->view.)lookat.eye.z;
moon_pos.x = sp60.x - camera->view.lookat.eye.x;
moon_pos.y = sp60.y - camera->view.lookat.eye.y;
moon_pos.z = sp60.z - camera->view.lookat.eye.z;
Vec vp, lp;
@@ -2300,7 +2281,7 @@ static void dKyr_draw_rev_moon(Mtx drawMtx, u8** tex) {
1.0f, 0.78f, 0.6f, 0.83f,
};
dKyr_get_vectle_calc(&view->lookat.eye, &view->lookat.center, &camfwd);
dKyr_get_vectle_calc(&camera->view.lookat.eye, &camera->view.lookat.center, &camfwd);
f32 cam_distXZ = JMAFastSqrt((camfwd.x * camfwd.x) + (camfwd.z * camfwd.z));
f32 cam_theta = atan2f(camfwd.x, camfwd.z);
@@ -2489,10 +2470,7 @@ void dKyr_drawSun(Mtx drawMtx, cXyz* ppos, GXColor& unused, u8** tex) {
sunpos.y = ppos->y;
sunpos.z = ppos->z;
#if TARGET_PC
dKyr_place_sun(camera, &sunpos);
view_class* const view = dKyr_draw_view(camera);
#endif
IF_DUSK(dKyr_place_sun(camera, &sunpos));
u32 stage_type = dStage_stagInfo_GetSTType(dComIfGp_getStage()->getStagInfo());
if (g_env_light.base_light.mColor.r == 0 && stage_type != ST_ROOM) {
@@ -2508,21 +2486,21 @@ void dKyr_drawSun(Mtx drawMtx, cXyz* ppos, GXColor& unused, u8** tex) {
spB4 = envlight->moon_pos;
moon_pos = spB4;
} else {
spB4 = DUSK_IF_ELSE(view->, camera->view.)lookat.eye + envlight->moon_pos;
moon_pos.x = spB4.x - DUSK_IF_ELSE(view->, camera->view.)lookat.eye.x;
moon_pos.y = spB4.y - DUSK_IF_ELSE(view->, camera->view.)lookat.eye.y;
moon_pos.z = spB4.z - DUSK_IF_ELSE(view->, camera->view.)lookat.eye.z;
spB4 = camera->view.lookat.eye + envlight->moon_pos;
moon_pos.x = spB4.x - camera->view.lookat.eye.x;
moon_pos.y = spB4.y - camera->view.lookat.eye.y;
moon_pos.z = spB4.z - camera->view.lookat.eye.z;
}
}
if (strcmp(dComIfGp_getStartStageName(), "F_SP103") == 0 && dKy_daynight_check()) {
spB4.x = 3900.0f + DUSK_IF_ELSE(view->, camera->view.)lookat.eye.x;
spB4.y = 8052.0f + DUSK_IF_ELSE(view->, camera->view.)lookat.eye.y;
spB4.z = -9072.0f + DUSK_IF_ELSE(view->, camera->view.)lookat.eye.z;
spB4.x = 3900.0f + camera->view.lookat.eye.x;
spB4.y = 8052.0f + camera->view.lookat.eye.y;
spB4.z = -9072.0f + camera->view.lookat.eye.z;
moon_pos.x = spB4.x - DUSK_IF_ELSE(view->, camera->view.)lookat.eye.x;
moon_pos.y = spB4.y - DUSK_IF_ELSE(view->, camera->view.)lookat.eye.y;
moon_pos.z = spB4.z - DUSK_IF_ELSE(view->, camera->view.)lookat.eye.z;
moon_pos.x = spB4.x - camera->view.lookat.eye.x;
moon_pos.y = spB4.y - camera->view.lookat.eye.y;
moon_pos.z = spB4.z - camera->view.lookat.eye.z;
}
int weekday = date % 8;
@@ -2668,9 +2646,8 @@ void dKyr_drawSun(Mtx drawMtx, cXyz* ppos, GXColor& unused, u8** tex) {
};
if (strcmp(dComIfGp_getStartStageName(), "F_SP200") != 0) {
dKyr_get_vectle_calc(DUSK_IF_ELSE(&view->, &camera->view.)lookat.eye,
DUSK_IF_ELSE(&view->, &camera->view.)lookat.center,
&camfwd);
dKyr_get_vectle_calc(&camera->view.lookat.eye,
&camera->view.lookat.center, &camfwd);
f32 cam_distXZ = JMAFastSqrt((camfwd.x * camfwd.x) + (camfwd.z * camfwd.z));
f32 cam_theta = atan2f(camfwd.x, camfwd.z);
f32 cam_phi = atan2f(camfwd.y, cam_distXZ);
@@ -4354,16 +4331,14 @@ void dKyr_drawStar(Mtx drawMtx, u8** tex) {
return;
}
IF_DUSK(view_class* const view = dKyr_draw_view(camera));
if (strcmp(dComIfGp_getStartStageName(), "F_SP200") == 0 && dComIfG_play_c::getLayerNo(0) == 0) {
moon_pos = envlight->moon_pos;
} else {
moon_pos = DUSK_IF_ELSE(view->, camera->view.)lookat.eye + envlight->moon_pos;
moon_pos = camera->view.lookat.eye + envlight->moon_pos;
if (sp38) {
moon_pos.x = 3900.0f + DUSK_IF_ELSE(view->, camera->view.)lookat.eye.x;
moon_pos.y = 8052.0f + DUSK_IF_ELSE(view->, camera->view.)lookat.eye.y;
moon_pos.z = -9072.0f + DUSK_IF_ELSE(view->, camera->view.)lookat.eye.z;
moon_pos.x = 3900.0f + camera->view.lookat.eye.x;
moon_pos.y = 8052.0f + camera->view.lookat.eye.y;
moon_pos.z = -9072.0f + camera->view.lookat.eye.z;
}
}
@@ -4403,9 +4378,9 @@ void dKyr_drawStar(Mtx drawMtx, u8** tex) {
rot = 0.0f;
}
spBC.x = DUSK_IF_ELSE(view->, camera->view.)lookat.eye.x;
spBC.y = DUSK_IF_ELSE(view->, camera->view.)lookat.eye.y;
spBC.z = DUSK_IF_ELSE(view->, camera->view.)lookat.eye.z;
spBC.x = camera->view.lookat.eye.x;
spBC.y = camera->view.lookat.eye.y;
spBC.z = camera->view.lookat.eye.z;
f32 sp34 = -1.0f;
int sp30 = 0;
+65
View File
@@ -0,0 +1,65 @@
#include "dusk/interp/dual_buffer.h"
#include <absl/container/flat_hash_map.h>
#include <vector>
namespace dusk::interp {
namespace {
struct Slot {
const void* type;
void* ptr;
void (*destroy)(void*);
};
using OwnerMap = absl::flat_hash_map<uintptr_t, std::vector<Slot>>;
OwnerMap& owner_map() {
static OwnerMap s_map;
return s_map;
}
} // namespace
void* detail::acquire(const void* key, const void* type, void* (*make)(), void (*destroy)(void*)) {
const uintptr_t id = reinterpret_cast<uintptr_t>(key);
auto& slots = owner_map()[id];
for (Slot& slot : slots) {
if (slot.type == type) {
return slot.ptr;
}
}
void* ptr = make();
slots.push_back({type, ptr, destroy});
return ptr;
}
void erase_owned_buffers(const void* key) {
if (key == nullptr) {
return;
}
OwnerMap& stored = owner_map();
auto it = stored.find(reinterpret_cast<uintptr_t>(key));
if (it == stored.end()) {
return;
}
for (Slot& slot : it->second) {
slot.destroy(slot.ptr);
}
stored.erase(it);
}
void clear_owned_buffers() {
OwnerMap& stored = owner_map();
for (auto& entry : stored) {
for (Slot& slot : entry.second) {
slot.destroy(slot.ptr);
}
}
stored.clear();
}
} // namespace dusk::interp
+123
View File
@@ -0,0 +1,123 @@
#pragma once
#include "dusk/interp/frame_interpolation.h"
#include "dusk/interp/lerp.h"
#include <cstring>
#ifdef __cplusplus
namespace dusk::interp {
template <typename T, int capacity>
class DualBuffer {
public:
explicit DualBuffer(T* dst = NULL)
: m_prev_valid(false),
m_curr_valid(false),
m_count(0),
m_dst(dst),
m_post(NULL),
m_post_user(NULL) {}
void bind(T* dst) { m_dst = dst; }
void reset() {
m_prev_valid = false;
m_curr_valid = false;
m_count = 0;
}
bool ready() const { return m_prev_valid && m_curr_valid; }
void capture_and_schedule(const T* src, int count, void (*post)(void*) = NULL,
void* post_user = NULL) {
roll();
capture(src, count);
schedule(post, post_user);
}
void writeback(T* src_and_dst, int count, void (*post)(void*) = NULL, void* post_user = NULL) {
bind(src_and_dst);
capture_and_schedule(src_and_dst, count, post, post_user);
}
private:
bool fits(int count) const {
if (count > capacity) {
return false;
}
return count > 0;
}
void roll() {
if (!is_enabled() || !m_curr_valid || m_count <= 0) {
return;
}
std::memcpy(m_prev, m_curr, static_cast<size_t>(m_count) * sizeof(T));
m_prev_valid = true;
}
void capture(const T* src, int count) {
if (!fits(count) || !is_enabled() || src == NULL) {
return;
}
std::memcpy(m_curr, src, static_cast<size_t>(count) * sizeof(T));
m_count = count;
m_curr_valid = true;
}
void apply(T* dst, int count) const {
if (!fits(count) || dst == NULL || !ready()) {
return;
}
const f32 step = get_interpolation_step();
for (int i = 0; i < count; ++i) {
lerp(dst[i], m_prev[i], m_curr[i], step);
}
}
void schedule(void (*post)(void*) = NULL, void* post_user = NULL) {
if (!is_enabled() || m_dst == NULL || !fits(m_count)) {
return;
}
m_post = post;
m_post_user = post_user;
add_interpolation_callback(&present_trampoline, this);
}
static void present_trampoline(void* user) { static_cast<DualBuffer*>(user)->present(); }
void present() {
apply(m_dst, m_count);
if (m_post != NULL) {
m_post(m_post_user);
}
}
T m_prev[capacity];
T m_curr[capacity];
bool m_prev_valid;
bool m_curr_valid;
int m_count;
T* m_dst;
void (*m_post)(void*);
void* m_post_user;
};
namespace detail {
void* acquire(const void* key, const void* type, void* (*make)(), void (*destroy)(void*));
}
template <typename Record>
Record& get(const void* key) {
static const char token{};
return *static_cast<Record*>(detail::acquire(
key, &token, []() -> void* { return new Record; },
[](void* p) { delete static_cast<Record*>(p); }));
}
void erase_owned_buffers(const void* key);
void clear_owned_buffers();
} // namespace dusk::interp
#endif
+6
View File
@@ -1,6 +1,7 @@
#include "dusk/interp/frame_interpolation.h"
#include "dusk/game_clock.h"
#include "dusk/interp/dual_buffer.h"
#include "dusk/interp/lerp.h"
#include "mtx.h"
@@ -103,6 +104,7 @@ void clear_interpolation_history() {
s_previousRecording = {};
s_currentRecording = {};
clear_replacements();
dusk::interp::clear_owned_buffers();
clear_callbacks();
dusk::interp::camera_invalidate_snapshots();
s_presentationDepth = 0;
@@ -143,6 +145,10 @@ bool is_enabled() {
return game_clock::g_frameTiming.interpolating;
}
bool should_capture() {
return is_enabled() && game_clock::is_sim_frame();
}
void begin_record() {
if (!is_enabled()) {
clear_interpolation_history();
+2
View File
@@ -19,6 +19,8 @@ bool presentation_sync_active();
bool is_enabled();
bool should_capture();
// TODO: These should be phased out as UI is progressively updated to use game_clock
void set_ui_tick_pending(bool value);
bool get_ui_tick_pending();
+159
View File
@@ -0,0 +1,159 @@
#include "dusk/interp/line.h"
#include "dusk/interp/dual_buffer.h"
#include "dusk/interp/frame_interpolation.h"
#include "dusk/interp/lerp.h"
#include "m_Do/m_Do_ext.h"
#include <cstdint>
#include <cstring>
#include <limits>
#include <new>
namespace {
struct Record {
Record()
: store(nullptr), previous(nullptr), current(nullptr), sample_capacity(0), tick(0),
strand_count(0), point_count(0), previous_valid(false), current_valid(false) {}
~Record() { delete[] store; }
Record(const Record&) = delete;
Record& operator=(const Record&) = delete;
void invalidate() {
previous_valid = false;
current_valid = false;
}
bool ensure(size_t required) {
if (required <= sample_capacity) {
return store != nullptr;
}
if (required > std::numeric_limits<size_t>::max() / (2 * sizeof(cXyz))) {
return false;
}
cXyz* next = new (std::nothrow) cXyz[required * 2];
if (next == nullptr) {
return false;
}
delete[] store;
store = next;
previous = store;
current = store + required;
sample_capacity = required;
invalidate();
return true;
}
cXyz* store;
cXyz* previous;
cXyz* current;
size_t sample_capacity;
uint64_t tick;
u16 strand_count;
u16 point_count;
bool previous_valid;
bool current_valid;
};
bool valid(const dusk::interp::line::Points& points) {
if (points.strands == nullptr || points.strand_count == 0 || points.point_count == 0) {
return false;
}
for (u16 strand = 0; strand < points.strand_count; ++strand) {
if (points.strands[strand].field_0x0 == nullptr) {
return false;
}
}
return true;
}
bool same_layout(const Record& record, const dusk::interp::line::Points& points) {
return record.current_valid && record.strand_count == points.strand_count &&
record.point_count == points.point_count;
}
void copy_points(cXyz* destination, const dusk::interp::line::Points& points) {
const size_t points_size = static_cast<size_t>(points.point_count) * sizeof(cXyz);
for (u16 strand = 0; strand < points.strand_count; ++strand) {
std::memcpy(destination + static_cast<size_t>(strand) * points.point_count,
points.strands[strand].field_0x0, points_size);
}
}
} // namespace
namespace dusk::interp::line {
void reset(const void* owner) {
erase_owned_buffers(owner);
}
void capture(const void* owner, Points points) {
if (owner == nullptr || !should_capture()) {
return;
}
Record& record = get<Record>(owner);
if (!valid(points)) {
record.invalidate();
return;
}
const size_t required = static_cast<size_t>(points.strand_count) * points.point_count;
if (!record.ensure(required)) {
record.invalidate();
return;
}
const uint64_t tick = sim_tick_seq();
const bool layout_matches = same_layout(record, points);
if (layout_matches && tick == record.tick) {
copy_points(record.current, points);
return;
}
if (layout_matches && tick == record.tick + 1) {
std::swap(record.previous, record.current);
record.previous_valid = true;
} else {
record.previous_valid = false;
}
copy_points(record.current, points);
record.tick = tick;
record.strand_count = points.strand_count;
record.point_count = points.point_count;
record.current_valid = true;
}
void write(const void* owner, Points points) {
if (owner == nullptr || !is_enabled() || !valid(points)) {
return;
}
Record& record = get<Record>(owner);
if (!record.previous_valid || !same_layout(record, points) ||
record.tick != sim_tick_seq())
{
return;
}
const f32 step = get_interpolation_step();
for (u16 strand = 0; strand < points.strand_count; ++strand) {
cXyz* destination = points.strands[strand].field_0x0;
const size_t offset = static_cast<size_t>(strand) * points.point_count;
for (u16 point = 0; point < points.point_count; ++point) {
lerp(destination[point], record.previous[offset + point],
record.current[offset + point], step);
}
}
}
} // namespace dusk::interp::line
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include "dolphin/types.h"
class mDoExt_3Dline_c;
namespace dusk::interp::line {
struct Points {
mDoExt_3Dline_c* strands;
u16 strand_count;
u16 point_count;
};
void reset(const void* owner);
void capture(const void* owner, Points points);
void write(const void* owner, Points points);
} // namespace dusk::interp::line
+5
View File
@@ -19,6 +19,10 @@
#include "c/c_dylink.h"
#include "m_Do/m_Do_printf.h"
#if TARGET_PC
#include "dusk/interp/dual_buffer.h"
#endif
#if DEBUG
class print_error_check_c {
public:
@@ -413,6 +417,7 @@ static int fopAc_Delete(void* i_this) {
#endif
if (ret == TRUE) {
IF_DUSK(dusk::interp::erase_owned_buffers(actor));
fopAcTg_ActorQTo(&actor->actor_tag);
fopDwTg_DrawQTo(&actor->draw_tag);
fopAcM_DeleteHeap((fopAc_ac_c*) i_this);
+67 -46
View File
@@ -26,8 +26,9 @@
#include <cstring>
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#include "dusk/game_clock.h"
#include "dusk/interp/frame_interpolation.h"
#include "dusk/interp/line.h"
#include "dusk/logging.h"
#include "dusk/version.hpp"
#endif
@@ -36,6 +37,16 @@ DUSK_GAME_DATA u8 mDoExt::CurrentHeapAdjustVerbose;
DUSK_GAME_DATA u8 mDoExt::HeapAdjustVerbose;
DUSK_GAME_DATA u8 mDoExt::HeapAdjustQuiet;
#if TARGET_PC
namespace {
enum InterpKind : u8 {
LINE_NONE,
LINE_UNIFORM_WIDTH,
LINE_PER_POINT_WIDTH,
};
} // namespace
#endif
static void mDoExt_setJ3DData(Mtx mtx, const J3DTransformInfo* transformInfo, u16 param_2) {
bool local_28;
if (cM3d_IsZero(transformInfo->mScale.x - 1.0f) && cM3d_IsZero(transformInfo->mScale.y - 1.0f) && cM3d_IsZero(transformInfo->mScale.z - 1.0f)) {
@@ -2364,6 +2375,12 @@ int mDoExt_3DlineMat0_c::init(u16 param_0, u16 param_1, int param_2) {
field_0x4 = NULL;
field_0x16 = 0;
#if TARGET_PC
mInterpWidth = 0.0f;
mInterpTaper = 0;
mInterpKind = LINE_NONE;
dusk::interp::line::reset(this);
#endif
return 1;
}
@@ -2443,6 +2460,12 @@ void mDoExt_3DlineMat0_c::update(int param_0, f32 param_1, GXColor& param_2, u16
field_0x14 = (u16)param_0;
}
#if TARGET_PC
mInterpWidth = param_1;
mInterpTaper = param_3;
mInterpKind = LINE_UNIFORM_WIDTH;
#endif
view_class* sp_2c = dComIfGd_getView();
mDoExt_3Dline_c* sp_28 = field_0x18;
@@ -2561,6 +2584,8 @@ void mDoExt_3DlineMat0_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
field_0x14 = (u16)param_0;
}
IF_DUSK(mInterpKind = LINE_PER_POINT_WIDTH);
view_class* sp_34 = dComIfGd_getView();
mDoExt_3Dline_c* sp_30 = field_0x18;
@@ -2678,7 +2703,10 @@ int mDoExt_3DlineMat1_c::init(u16 param_0, u16 param_1, ResTIMG* param_2, int pa
field_0x4 = 0;
mIsDrawn = 0;
#if TARGET_PC
mInterpLineKind = 0;
mInterpWidth = 0.0f;
mInterpTaper = 0;
mInterpKind = LINE_NONE;
dusk::interp::line::reset(this);
#endif
GXInitTexObj(&mTextureObject, (void*)((intptr_t)param_2 + param_2->imageOffset), param_2->width,
@@ -2762,11 +2790,7 @@ void mDoExt_3DlineMat1_c::draw() {
}
}
#if TARGET_PC
void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3, dKy_tevstr_c* param_4, const cXyz* presentationEye) {
#else
void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3, dKy_tevstr_c* param_4) {
#endif
mColor = param_2;
this->mpTevStr = param_4;
if (param_0 < 0) {
@@ -2778,9 +2802,9 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
}
#if TARGET_PC
mInterpLineKind = 1;
mInterpLineF = param_1;
mInterpLineU16 = param_3;
mInterpWidth = param_1;
mInterpTaper = param_3;
mInterpKind = LINE_UNIFORM_WIDTH;
#endif
view_class* sp_3c = dComIfGd_getView();
@@ -2836,12 +2860,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
local_f31 += local_f30 * 0.02f * (8.0f / param_1);
}
#if TARGET_PC
const cXyz& lineEye = (presentationEye != nullptr && dusk::interp::is_enabled()) ? *presentationEye : sp_3c->lookat.eye;
sp_13c = *local_r27 - lineEye;
#else
sp_13c = *local_r27 - sp_3c->lookat.eye;
#endif
sp_130 = sp_130.outprod(sp_13c);
sp_130.normalizeZP();
@@ -2876,11 +2895,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
local_f31 += local_f30 * 0.02f * (8.0f / param_1);
}
#if TARGET_PC
sp_13c = local_r27[0] - lineEye;
#else
sp_13c = local_r27[0] - sp_3c->lookat.eye;
#endif
sp_130 = sp_130.outprod(sp_13c);
sp_130.normalizeZP();
@@ -2953,11 +2968,7 @@ void mDoExt_3DlineMat2_c::setMaterial() {
GXLoadNrmMtxImm(cMtx_getIdentity(), 0);
}
#if TARGET_PC
void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* param_4, const cXyz* presentationEye) {
#else
void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* param_4
#endif
void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* param_4) {
mColor = param_2;
this->mpTevStr = param_4;
if (param_0 < 0) {
@@ -2968,9 +2979,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
field_0x34 = param_0;
}
#if TARGET_PC
mInterpLineKind = 2;
#endif
IF_DUSK(mInterpKind = LINE_PER_POINT_WIDTH);
view_class* stack_3c = dComIfGd_getView();
mDoExt_3Dline_c* sp_38 = mpLines;
@@ -2997,12 +3006,6 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
for (s32 sp_14 = 0; sp_14 < mNumLines; sp_14++) {
local_r27 = sp_38[0].field_0x0;
size_p = sp_38->field_0x4;
#if TARGET_PC
if (presentationEye != nullptr && dusk::interp::is_enabled() && size_p == NULL) {
sp_38 += 1;
continue;
}
#endif
JUT_ASSERT(5875, size_p != NULL);
sp_24 = sp_38->field_0x8[mIsDrawn];
sp_28 = sp_24;
@@ -3016,12 +3019,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
sp_130 = local_r27[1] - local_r27[0];
local_f30 = sp_130.abs();
local_f31 += local_f30 * 0.1f;
#if TARGET_PC
const cXyz& lineEye = (presentationEye != nullptr && dusk::interp::is_enabled()) ? *presentationEye : stack_3c->lookat.eye;
sp_13c = local_r27[0] - lineEye;
#else
sp_13c = local_r27[0] - stack_3c->lookat.eye;
#endif
sp_130 = sp_130.outprod(sp_13c);
sp_130.normalizeZP();
local_r30->x = sp_130.x * 64.0f;
@@ -3043,11 +3041,7 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
sp_130 = local_r27[1] - local_r27[0];
local_f30 = sp_130.abs();
local_f31 += local_f30 * 0.1f;
#if TARGET_PC
sp_13c = local_r27[0] - lineEye;
#else
sp_13c = local_r27[0] - stack_3c->lookat.eye;
#endif
sp_130 = sp_130.outprod(sp_13c);
sp_130.normalizeZP();
local_r30 += 2;
@@ -3092,16 +3086,42 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
}
#if TARGET_PC
void mDoExt_3DlineMat1_c::refreshGeometryForPresentationEye(const cXyz& eye) {
namespace {
template <typename Material>
void refresh_3dline_geometry(Material* material, dusk::interp::line::Points points, u8 kind,
f32 width, u16 taper, GXColor& color, dKy_tevstr_c* tevStr) {
if (!dusk::interp::is_enabled()) {
return;
}
if (mInterpLineKind == 1) {
update(field_0x34, mInterpLineF, mColor, mInterpLineU16, mpTevStr, &eye);
} else if (mInterpLineKind == 2) {
update(field_0x34, mColor, mpTevStr, &eye);
dusk::interp::line::write(material, points);
if (kind == LINE_UNIFORM_WIDTH) {
material->update(points.point_count, width, color, taper, tevStr);
} else if (kind == LINE_PER_POINT_WIDTH) {
material->update(points.point_count, color, tevStr);
}
}
} // namespace
void mDoExt_3DlineMat0_c::captureInterpPoints() {
dusk::interp::line::capture(this, {field_0x18, field_0x10, field_0x14});
}
void mDoExt_3DlineMat0_c::refreshGeometryForPresentation() {
refresh_3dline_geometry(this, {field_0x18, field_0x10, field_0x14}, mInterpKind,
mInterpWidth, mInterpTaper, field_0x8, field_0xc);
}
void mDoExt_3DlineMat1_c::captureInterpPoints() {
dusk::interp::line::capture(this, {mpLines, mNumLines, field_0x34});
}
void mDoExt_3DlineMat1_c::refreshGeometryForPresentation() {
refresh_3dline_geometry(this, {mpLines, mNumLines, field_0x34}, mInterpKind,
mInterpWidth, mInterpTaper, mColor, mpTevStr);
}
#endif
void mDoExt_3DlineMatSortPacket::setMat(mDoExt_3DlineMat_c* i_3DlineMat) {
@@ -3110,6 +3130,7 @@ void mDoExt_3DlineMatSortPacket::setMat(mDoExt_3DlineMat_c* i_3DlineMat) {
}
i_3DlineMat->field_0x4 = mp3DlineMat;
mp3DlineMat = i_3DlineMat;
IF_DUSK(i_3DlineMat->captureInterpPoints());
}
void mDoExt_3DlineMatSortPacket::draw() {
+1 -7
View File
@@ -55,8 +55,6 @@
#include "helpers/endian.h"
#include "helpers/gx_helper.h"
#include "d/actor/d_a_horse.h"
#include <aurora/lib/window.hpp>
#include <SDL3/SDL_video.h>
#include <tracy/Tracy.hpp>
@@ -2406,11 +2404,7 @@ int mDoGph_Painter() {
#if TARGET_PC
if (dusk::interp::is_enabled()) {
// FRAME INTERP NOTE: Currently only recalculating points for Epona's reins. Need a more global solution.
if (daHorse_c* horse = dComIfGp_getHorseActor()) {
horse->lerpControlPoints(dusk::interp::get_interpolation_step());
}
g_dComIfG_gameInfo.drawlist.refresh3DlineMats(camera_p->view.lookat.eye);
g_dComIfG_gameInfo.drawlist.refresh3DlineMats();
}
#endif