From 83f50329d84c89722f5fa65e084a157d8cb4b9a1 Mon Sep 17 00:00:00 2001 From: Irastris Date: Sun, 6 Sep 2026 19:14:00 -0400 Subject: [PATCH] Refactor chain and line interpolation, revert portion of last PR (#2397) * Consolidate chain interpolation * 3D lines interpolate themselves * Revert d_kankyo_rain camera changes --- files.cmake | 2 + include/d/actor/d_a_alink.h | 23 ---- include/d/actor/d_a_b_gnd.h | 6 - include/d/actor/d_a_e_db.h | 6 - include/d/actor/d_a_e_hb.h | 6 - include/d/actor/d_a_e_mb.h | 6 - include/d/actor/d_a_e_s1.h | 9 -- include/d/actor/d_a_e_wb.h | 6 - include/d/actor/d_a_e_yd.h | 6 - include/d/actor/d_a_e_yg.h | 9 -- include/d/actor/d_a_e_yh.h | 6 - include/d/actor/d_a_horse.h | 3 - include/d/actor/d_a_mg_rod.h | 7 -- include/d/actor/d_a_obj_fchain.h | 12 -- include/d/actor/d_a_obj_keyhole.h | 7 -- include/d/actor/d_a_obj_klift00.h | 9 +- include/d/d_drawlist.h | 2 +- include/m_Do/m_Do_ext.h | 27 ++-- src/d/actor/d_a_alink.cpp | 64 +++++----- src/d/actor/d_a_alink_hook.inc | 42 ++----- src/d/actor/d_a_b_gnd.cpp | 39 ------ src/d/actor/d_a_e_db.cpp | 31 ----- src/d/actor/d_a_e_hb.cpp | 31 ----- src/d/actor/d_a_e_mb.cpp | 31 ----- src/d/actor/d_a_e_s1.cpp | 51 -------- src/d/actor/d_a_e_wb.cpp | 40 +----- src/d/actor/d_a_e_yd.cpp | 31 ----- src/d/actor/d_a_e_yg.cpp | 52 -------- src/d/actor/d_a_e_yh.cpp | 31 ----- src/d/actor/d_a_horse.cpp | 58 --------- src/d/actor/d_a_mg_rod.cpp | 49 -------- src/d/actor/d_a_obj_fchain.cpp | 42 +------ src/d/actor/d_a_obj_keyhole.cpp | 39 ------ src/d/actor/d_a_obj_klift00.cpp | 50 ++++---- src/d/d_drawlist.cpp | 4 +- src/d/d_kankyo_rain.cpp | 111 +++++++---------- src/dusk/interp/dual_buffer.cpp | 65 ++++++++++ src/dusk/interp/dual_buffer.h | 123 ++++++++++++++++++ src/dusk/interp/frame_interpolation.cpp | 6 + src/dusk/interp/frame_interpolation.h | 2 + src/dusk/interp/line.cpp | 159 ++++++++++++++++++++++++ src/dusk/interp/line.h | 19 +++ src/f_op/f_op_actor.cpp | 5 + src/m_Do/m_Do_ext.cpp | 113 ++++++++++------- src/m_Do/m_Do_graphic.cpp | 8 +- 45 files changed, 581 insertions(+), 867 deletions(-) create mode 100644 src/dusk/interp/dual_buffer.cpp create mode 100644 src/dusk/interp/dual_buffer.h create mode 100644 src/dusk/interp/line.cpp create mode 100644 src/dusk/interp/line.h diff --git a/files.cmake b/files.cmake index 665ce62330..5c7a9223a2 100644 --- a/files.cmake +++ b/files.cmake @@ -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 diff --git a/include/d/actor/d_a_alink.h b/include/d/actor/d_a_alink.h index 75ac1aac2b..a0b70747bc 100644 --- a/include/d/actor/d_a_alink.h +++ b/include/d/actor/d_a_alink.h @@ -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 diff --git a/include/d/actor/d_a_b_gnd.h b/include/d/actor/d_a_b_gnd.h index 0827102eec..dcf6c94905 100644 --- a/include/d/actor/d_a_b_gnd.h +++ b/include/d/actor/d_a_b_gnd.h @@ -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 }; diff --git a/include/d/actor/d_a_e_db.h b/include/d/actor/d_a_e_db.h index 4f10715443..a95722a6d1 100644 --- a/include/d/actor/d_a_e_db.h +++ b/include/d/actor/d_a_e_db.h @@ -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); diff --git a/include/d/actor/d_a_e_hb.h b/include/d/actor/d_a_e_hb.h index 3069bcd325..a7e0241007 100644 --- a/include/d/actor/d_a_e_hb.h +++ b/include/d/actor/d_a_e_hb.h @@ -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); diff --git a/include/d/actor/d_a_e_mb.h b/include/d/actor/d_a_e_mb.h index 527cf30eac..f36c744879 100644 --- a/include/d/actor/d_a_e_mb.h +++ b/include/d/actor/d_a_e_mb.h @@ -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); diff --git a/include/d/actor/d_a_e_s1.h b/include/d/actor/d_a_e_s1.h index 5cbae84696..a631ba47ac 100644 --- a/include/d/actor/d_a_e_s1.h +++ b/include/d/actor/d_a_e_s1.h @@ -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); diff --git a/include/d/actor/d_a_e_wb.h b/include/d/actor/d_a_e_wb.h index aecbac96a1..770e537f2e 100644 --- a/include/d/actor/d_a_e_wb.h +++ b/include/d/actor/d_a_e_wb.h @@ -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 }; diff --git a/include/d/actor/d_a_e_yd.h b/include/d/actor/d_a_e_yd.h index 44d6036600..188e435ba5 100644 --- a/include/d/actor/d_a_e_yd.h +++ b/include/d/actor/d_a_e_yd.h @@ -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); diff --git a/include/d/actor/d_a_e_yg.h b/include/d/actor/d_a_e_yg.h index 6be19933cb..69a85430a8 100644 --- a/include/d/actor/d_a_e_yg.h +++ b/include/d/actor/d_a_e_yg.h @@ -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); diff --git a/include/d/actor/d_a_e_yh.h b/include/d/actor/d_a_e_yh.h index 63e8ac1882..519e5e2779 100644 --- a/include/d/actor/d_a_e_yh.h +++ b/include/d/actor/d_a_e_yh.h @@ -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); diff --git a/include/d/actor/d_a_horse.h b/include/d/actor/d_a_horse.h index bb7ce7ccb1..2074570517 100644 --- a/include/d/actor/d_a_horse.h +++ b/include/d/actor/d_a_horse.h @@ -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(); diff --git a/include/d/actor/d_a_mg_rod.h b/include/d/actor/d_a_mg_rod.h index 97a0bb1c72..76863f33d5 100644 --- a/include/d/actor/d_a_mg_rod.h +++ b/include/d/actor/d_a_mg_rod.h @@ -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 */ diff --git a/include/d/actor/d_a_obj_fchain.h b/include/d/actor/d_a_obj_fchain.h index 80e96f097b..e9250fbe24 100644 --- a/include/d/actor/d_a_obj_fchain.h +++ b/include/d/actor/d_a_obj_fchain.h @@ -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); diff --git a/include/d/actor/d_a_obj_keyhole.h b/include/d/actor/d_a_obj_keyhole.h index dac1b02696..fd39641ad8 100644 --- a/include/d/actor/d_a_obj_keyhole.h +++ b/include/d/actor/d_a_obj_keyhole.h @@ -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); diff --git a/include/d/actor/d_a_obj_klift00.h b/include/d/actor/d_a_obj_klift00.h index d87c2d4459..a41c5c7b5c 100644 --- a/include/d/actor/d_a_obj_klift00.h +++ b/include/d/actor/d_a_obj_klift00.h @@ -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); diff --git a/include/d/d_drawlist.h b/include/d/d_drawlist.h index f792f544cc..4baf6ed324 100644 --- a/include/d/d_drawlist.h +++ b/include/d/d_drawlist.h @@ -441,7 +441,7 @@ public: } #if TARGET_PC - void refresh3DlineMats(const cXyz& eye); + void refresh3DlineMats(); #endif void peekZdata() { mPeekZ.peekData(); } diff --git a/include/m_Do/m_Do_ext.h b/include/m_Do/m_Do_ext.h index bd1baac2df..4c1ceeb997 100644 --- a/include/m_Do/m_Do_ext.h +++ b/include/m_Do/m_Do_ext.h @@ -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 { diff --git a/src/d/actor/d_a_alink.cpp b/src/d/actor/d_a_alink.cpp index c9a2969914..02552022a8 100644 --- a/src/d/actor/d_a_alink.cpp +++ b/src/d/actor/d_a_alink.cpp @@ -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 +#include + +static const int IRON_BALL_CHAIN_COUNT = 102; +static const int HS_CHAIN_ANCHOR_COUNT = 4; + +namespace { +struct AlinkInterp { + dusk::interp::DualBuffer ib_pos; + dusk::interp::DualBuffer ib_angle; + dusk::interp::DualBuffer ib_hand; + cXyz hs_draw[HS_CHAIN_ANCHOR_COUNT]; + dusk::interp::DualBuffer 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(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(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 diff --git a/src/d/actor/d_a_alink_hook.inc b/src/d/actor/d_a_alink_hook.inc index 1f82ef98c1..9e4e7090f8 100644 --- a/src/d/actor/d_a_alink_hook.inc +++ b/src/d/actor/d_a_alink_hook.inc @@ -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(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(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()) { diff --git a/src/d/actor/d_a_b_gnd.cpp b/src/d/actor/d_a_b_gnd.cpp index 518590d854..42eeac303a 100644 --- a/src/d/actor/d_a_b_gnd.cpp +++ b/src/d/actor/d_a_b_gnd.cpp @@ -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; diff --git a/src/d/actor/d_a_e_db.cpp b/src/d/actor/d_a_e_db.cpp index 217e32e16e..65f91843a3 100644 --- a/src/d/actor/d_a_e_db.cpp +++ b/src/d/actor/d_a_e_db.cpp @@ -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) { diff --git a/src/d/actor/d_a_e_hb.cpp b/src/d/actor/d_a_e_hb.cpp index f73e2bae0b..b39f4750a1 100644 --- a/src/d/actor/d_a_e_hb.cpp +++ b/src/d/actor/d_a_e_hb.cpp @@ -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) { diff --git a/src/d/actor/d_a_e_mb.cpp b/src/d/actor/d_a_e_mb.cpp index 8e40e92baa..9eaef0cc1c 100644 --- a/src/d/actor/d_a_e_mb.cpp +++ b/src/d/actor/d_a_e_mb.cpp @@ -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; } diff --git a/src/d/actor/d_a_e_s1.cpp b/src/d/actor/d_a_e_s1.cpp index 4f6b6c3c95..3c7c6700e5 100644 --- a/src/d/actor/d_a_e_s1.cpp +++ b/src/d/actor/d_a_e_s1.cpp @@ -16,10 +16,6 @@ #include "f_op/f_op_camera_mng.h" #include -#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) { diff --git a/src/d/actor/d_a_e_wb.cpp b/src/d/actor/d_a_e_wb.cpp index cadbaf4aed..cf9e4ccbf7 100644 --- a/src/d/actor/d_a_e_wb.cpp +++ b/src/d/actor/d_a_e_wb.cpp @@ -21,6 +21,7 @@ #include #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; diff --git a/src/d/actor/d_a_e_yd.cpp b/src/d/actor/d_a_e_yd.cpp index 198e59ac06..bdc7c527e2 100644 --- a/src/d/actor/d_a_e_yd.cpp +++ b/src/d/actor/d_a_e_yd.cpp @@ -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); diff --git a/src/d/actor/d_a_e_yg.cpp b/src/d/actor/d_a_e_yg.cpp index 2267004353..e6bcd05098 100644 --- a/src/d/actor/d_a_e_yg.cpp +++ b/src/d/actor/d_a_e_yg.cpp @@ -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; diff --git a/src/d/actor/d_a_e_yh.cpp b/src/d/actor/d_a_e_yh.cpp index 137f87fc92..55f175d78e 100644 --- a/src/d/actor/d_a_e_yh.cpp +++ b/src/d/actor/d_a_e_yh.cpp @@ -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) { diff --git a/src/d/actor/d_a_horse.cpp b/src/d/actor/d_a_horse.cpp index 76cd1404eb..b738460bb8 100644 --- a/src/d/actor/d_a_horse.cpp +++ b/src/d/actor/d_a_horse.cpp @@ -20,22 +20,6 @@ #include #include -#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); diff --git a/src/d/actor/d_a_mg_rod.cpp b/src/d/actor/d_a_mg_rod.cpp index 07d6b7b10c..53dba36b74 100644 --- a/src/d/actor/d_a_mg_rod.cpp +++ b/src/d/actor/d_a_mg_rod.cpp @@ -26,7 +26,6 @@ #include #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; diff --git a/src/d/actor/d_a_obj_fchain.cpp b/src/d/actor/d_a_obj_fchain.cpp index 305a57ae34..cf2470fc17 100644 --- a/src/d/actor/d_a_obj_fchain.cpp +++ b/src/d/actor/d_a_obj_fchain.cpp @@ -13,7 +13,10 @@ #include #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 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(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, ¤t.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(this).writeback(field_0x694, CHAIN_COUNT)); } return 1; } diff --git a/src/d/actor/d_a_obj_keyhole.cpp b/src/d/actor/d_a_obj_keyhole.cpp index 68df1e1784..8b120f77e3 100644 --- a/src/d/actor/d_a_obj_keyhole.cpp +++ b/src/d/actor/d_a_obj_keyhole.cpp @@ -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) { diff --git a/src/d/actor/d_a_obj_klift00.cpp b/src/d/actor/d_a_obj_klift00.cpp index 8b9d485869..8a0eb5e38e 100644 --- a/src/d/actor/d_a_obj_klift00.cpp +++ b/src/d/actor/d_a_obj_klift00.cpp @@ -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 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(pUserWork)->onInterpCallback(); +static void klift00_interp_post(void* pUserWork) { + static_cast(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(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(this).chain.capture_and_schedule(curr, mNumChains, &klift00_interp_post, this); } #endif diff --git a/src/d/d_drawlist.cpp b/src/d/d_drawlist.cpp index 693b47eed3..b5ed876126 100644 --- a/src/d/d_drawlist.cpp +++ b/src/d/d_drawlist.cpp @@ -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(); } } } diff --git a/src/d/d_kankyo_rain.cpp b/src/d/d_kankyo_rain.cpp index 5fbcef3b65..dc01322291 100644 --- a/src/d/d_kankyo_rain.cpp +++ b/src/d/d_kankyo_rain.cpp @@ -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& 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; diff --git a/src/dusk/interp/dual_buffer.cpp b/src/dusk/interp/dual_buffer.cpp new file mode 100644 index 0000000000..be1160e6a6 --- /dev/null +++ b/src/dusk/interp/dual_buffer.cpp @@ -0,0 +1,65 @@ +#include "dusk/interp/dual_buffer.h" + +#include +#include + +namespace dusk::interp { +namespace { + +struct Slot { + const void* type; + void* ptr; + void (*destroy)(void*); +}; + +using OwnerMap = absl::flat_hash_map>; + +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(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(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 diff --git a/src/dusk/interp/dual_buffer.h b/src/dusk/interp/dual_buffer.h new file mode 100644 index 0000000000..bbae6a3a01 --- /dev/null +++ b/src/dusk/interp/dual_buffer.h @@ -0,0 +1,123 @@ +#pragma once + +#include "dusk/interp/frame_interpolation.h" +#include "dusk/interp/lerp.h" + +#include + +#ifdef __cplusplus +namespace dusk::interp { + +template +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(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(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(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 +Record& get(const void* key) { + static const char token{}; + return *static_cast(detail::acquire( + key, &token, []() -> void* { return new Record; }, + [](void* p) { delete static_cast(p); })); +} + +void erase_owned_buffers(const void* key); +void clear_owned_buffers(); + +} // namespace dusk::interp +#endif diff --git a/src/dusk/interp/frame_interpolation.cpp b/src/dusk/interp/frame_interpolation.cpp index ceceb710e0..4edfee234a 100644 --- a/src/dusk/interp/frame_interpolation.cpp +++ b/src/dusk/interp/frame_interpolation.cpp @@ -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(); diff --git a/src/dusk/interp/frame_interpolation.h b/src/dusk/interp/frame_interpolation.h index 57f079ad00..64ae2acec4 100644 --- a/src/dusk/interp/frame_interpolation.h +++ b/src/dusk/interp/frame_interpolation.h @@ -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(); diff --git a/src/dusk/interp/line.cpp b/src/dusk/interp/line.cpp new file mode 100644 index 0000000000..3d509debea --- /dev/null +++ b/src/dusk/interp/line.cpp @@ -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 +#include +#include +#include + +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::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(points.point_count) * sizeof(cXyz); + for (u16 strand = 0; strand < points.strand_count; ++strand) { + std::memcpy(destination + static_cast(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(owner); + if (!valid(points)) { + record.invalidate(); + return; + } + + const size_t required = static_cast(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(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(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 diff --git a/src/dusk/interp/line.h b/src/dusk/interp/line.h new file mode 100644 index 0000000000..7b4f3b56bc --- /dev/null +++ b/src/dusk/interp/line.h @@ -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 diff --git a/src/f_op/f_op_actor.cpp b/src/f_op/f_op_actor.cpp index 4e5940eec4..db85ea3bf3 100644 --- a/src/f_op/f_op_actor.cpp +++ b/src/f_op/f_op_actor.cpp @@ -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); diff --git a/src/m_Do/m_Do_ext.cpp b/src/m_Do/m_Do_ext.cpp index bf00990942..a53275b7fb 100644 --- a/src/m_Do/m_Do_ext.cpp +++ b/src/m_Do/m_Do_ext.cpp @@ -26,8 +26,9 @@ #include #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 +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() { diff --git a/src/m_Do/m_Do_graphic.cpp b/src/m_Do/m_Do_graphic.cpp index a203163192..f83f151724 100644 --- a/src/m_Do/m_Do_graphic.cpp +++ b/src/m_Do/m_Do_graphic.cpp @@ -55,8 +55,6 @@ #include "helpers/endian.h" #include "helpers/gx_helper.h" -#include "d/actor/d_a_horse.h" - #include #include #include @@ -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