diff --git a/include/d/actor/d_a_e_db.h b/include/d/actor/d_a_e_db.h index a95722a6d1..4f10715443 100644 --- a/include/d/actor/d_a_e_db.h +++ b/include/d/actor/d_a_e_db.h @@ -80,6 +80,12 @@ 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 a7e0241007..3069bcd325 100644 --- a/include/d/actor/d_a_e_hb.h +++ b/include/d/actor/d_a_e_hb.h @@ -73,6 +73,12 @@ 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_s1.h b/include/d/actor/d_a_e_s1.h index a631ba47ac..5cbae84696 100644 --- a/include/d/actor/d_a_e_s1.h +++ b/include/d/actor/d_a_e_s1.h @@ -81,6 +81,15 @@ public: /* 0x306D */ u8 field_0x306D[0x307C - 0x306D]; /* 0x307C */ u32 mBodyEffEmtrID; /* 0x3080 */ u8 mInitHIO; + +#if TARGET_PC + static const int HAIR_STRAND_COUNT = 22; + static const int HAIR_SEGMENT_COUNT = 16; + cXyz mHairInterpPrev[HAIR_STRAND_COUNT * HAIR_SEGMENT_COUNT]; + cXyz mHairInterpCurr[HAIR_STRAND_COUNT * HAIR_SEGMENT_COUNT]; + bool mHairInterpPrevValid; + bool mHairInterpCurrValid; +#endif }; STATIC_ASSERT(sizeof(e_s1_class) == 0x3084); diff --git a/include/d/actor/d_a_e_yd.h b/include/d/actor/d_a_e_yd.h index 188e435ba5..44d6036600 100644 --- a/include/d/actor/d_a_e_yd.h +++ b/include/d/actor/d_a_e_yd.h @@ -74,6 +74,12 @@ 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 69a85430a8..6be19933cb 100644 --- a/include/d/actor/d_a_e_yg.h +++ b/include/d/actor/d_a_e_yg.h @@ -63,6 +63,15 @@ public: /* 0x0BB4 */ yg_ke_s mYgKes[13]; /* 0x1880 */ mDoExt_3DlineMat0_c mLineMat; /* 0x189C */ u8 mIsFirstSpawn; + +#if TARGET_PC + static const int TENTACLE_STRAND_COUNT = 13; + static const int TENTACLE_SEGMENT_COUNT = 10; + cXyz mTentacleInterpPrev[TENTACLE_STRAND_COUNT * TENTACLE_SEGMENT_COUNT]; + cXyz mTentacleInterpCurr[TENTACLE_STRAND_COUNT * TENTACLE_SEGMENT_COUNT]; + bool mTentacleInterpPrevValid; + bool mTentacleInterpCurrValid; +#endif }; STATIC_ASSERT(sizeof(e_yg_class) == 0x18a0); diff --git a/include/d/actor/d_a_e_yh.h b/include/d/actor/d_a_e_yh.h index 519e5e2779..63e8ac1882 100644 --- a/include/d/actor/d_a_e_yh.h +++ b/include/d/actor/d_a_e_yh.h @@ -77,6 +77,12 @@ 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_obj_fchain.h b/include/d/actor/d_a_obj_fchain.h index 1bd7b9a810..7c4ae74faf 100644 --- a/include/d/actor/d_a_obj_fchain.h +++ b/include/d/actor/d_a_obj_fchain.h @@ -31,6 +31,10 @@ public: csXyz* getAngle() { return field_0x8a4; } J3DModelData* getModelData() { return mModelData; } +#if TARGET_PC + void onInterpCallback(); +#endif + private: /* 0x568 */ request_of_phase_process_class mPhase; /* 0x570 */ J3DModelData* mModelData; @@ -42,6 +46,14 @@ private: /* 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/src/d/actor/d_a_e_db.cpp b/src/d/actor/d_a_e_db.cpp index cbd21176b9..4d60fbd6f6 100644 --- a/src/d/actor/d_a_e_db.cpp +++ b/src/d/actor/d_a_e_db.cpp @@ -10,6 +10,10 @@ #include "f_op/f_op_kankyo_mng.h" #include "f_op/f_op_actor_enemy.h" +#if TARGET_PC +#include "dusk/frame_interpolation.h" +#endif + class daE_DB_HIO_c : public JORReflexible { public: daE_DB_HIO_c(); @@ -66,6 +70,22 @@ 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(bool isSimFrame, void* pUserWork) { + e_db_class* i_this = (e_db_class*)pUserWork; + if (!i_this->mStalkLineInterpPrevValid || !i_this->mStalkLineInterpCurrValid) { + return; + } + const f32 alpha = dusk::frame_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; @@ -95,6 +115,17 @@ 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::getSettings().game.enableFrameInterpolation) { + 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::frame_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 d3177ba0f6..8ed9058c6f 100644 --- a/src/d/actor/d_a_e_hb.cpp +++ b/src/d/actor/d_a_e_hb.cpp @@ -9,6 +9,10 @@ #include "d/actor/d_a_e_hb_leaf.h" #include "f_op/f_op_actor_enemy.h" +#if TARGET_PC +#include "dusk/frame_interpolation.h" +#endif + enum daE_HB_ACTION { ACTION_STAY, ACTION_APPEAR, @@ -64,6 +68,22 @@ 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(bool isSimFrame, void* pUserWork) { + e_hb_class* i_this = (e_hb_class*)pUserWork; + if (!i_this->mStalkLineInterpPrevValid || !i_this->mStalkLineInterpCurrValid) { + return; + } + const f32 alpha = dusk::frame_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; @@ -82,6 +102,17 @@ 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::getSettings().game.enableFrameInterpolation) { + 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::frame_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_s1.cpp b/src/d/actor/d_a_e_s1.cpp index 4586969cf5..db87e1294f 100644 --- a/src/d/actor/d_a_e_s1.cpp +++ b/src/d/actor/d_a_e_s1.cpp @@ -17,6 +17,8 @@ #include "d/d_s_play.h" #include "f_op/f_op_actor_enemy.h" #include "f_op/f_op_camera_mng.h" +#include "dusk/frame_interpolation.h" +#include "dusk/settings.h" #include class daE_S1_HIO_c { @@ -102,6 +104,25 @@ static void anm_init(e_s1_class* i_this, int i_resNo, f32 i_morf, u8 i_attr, f32 i_this->mAnm = i_resNo; } +#if TARGET_PC +static void daE_S1_interp_callback(bool isSimFrame, void* pUserWork) { + e_s1_class* i_this = (e_s1_class*)pUserWork; + if (!i_this->mHairInterpPrevValid || !i_this->mHairInterpCurrValid) { + return; + } + const f32 alpha = dusk::frame_interp::get_interpolation_step(); + for (int s = 0; s < e_s1_class::HAIR_STRAND_COUNT; s++) { + cXyz* dst = i_this->mLineMat.getPos(s); + for (int i = 0; i < e_s1_class::HAIR_SEGMENT_COUNT; i++) { + int idx = s * e_s1_class::HAIR_SEGMENT_COUNT + i; + const cXyz& p0 = i_this->mHairInterpPrev[idx]; + const cXyz& p1 = i_this->mHairInterpCurr[idx]; + dst[i] = p0 + (p1 - p0) * alpha; + } + } +} +#endif + static int daE_S1_Draw(e_s1_class* i_this) { if (i_this->field_0x306c != 0) { return 1; @@ -135,6 +156,22 @@ static int daE_S1_Draw(e_s1_class* i_this) { i_this->mLineMat.update(16, line_color, &i_this->tevStr); dComIfGd_set3DlineMatDark(&i_this->mLineMat); +#if TARGET_PC + if (dusk::getSettings().game.enableFrameInterpolation) { + if (i_this->mHairInterpCurrValid) { + memcpy(i_this->mHairInterpPrev, i_this->mHairInterpCurr, sizeof(i_this->mHairInterpCurr)); + i_this->mHairInterpPrevValid = true; + } + for (int s = 0; s < e_s1_class::HAIR_STRAND_COUNT; s++) { + cXyz* src = i_this->mLineMat.getPos(s); + memcpy(&i_this->mHairInterpCurr[s * e_s1_class::HAIR_SEGMENT_COUNT], src, + e_s1_class::HAIR_SEGMENT_COUNT * sizeof(cXyz)); + } + i_this->mHairInterpCurrValid = true; + dusk::frame_interp::add_interpolation_callback(&daE_S1_interp_callback, i_this); + } +#endif + dComIfGd_setList(); return 1; } @@ -2164,6 +2201,11 @@ static int daE_S1_Create(fopAc_ac_c* i_this) { return cPhs_ERROR_e; } +#if TARGET_PC + a_this->mHairInterpPrevValid = false; + a_this->mHairInterpCurrValid = false; +#endif + OS_REPORT("//////////////E_S1 SET 2 !!\n"); if (path_no != 0xFF) { diff --git a/src/d/actor/d_a_e_yd.cpp b/src/d/actor/d_a_e_yd.cpp index bdcd044eed..18809e05ea 100644 --- a/src/d/actor/d_a_e_yd.cpp +++ b/src/d/actor/d_a_e_yd.cpp @@ -12,6 +12,10 @@ #include "d/d_cc_uty.h" #include "f_op/f_op_actor_enemy.h" +#if TARGET_PC +#include "dusk/frame_interpolation.h" +#endif + class daE_YD_HIO_c { public: daE_YD_HIO_c(); @@ -73,6 +77,22 @@ 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(bool isSimFrame, void* pUserWork) { + e_yd_class* i_this = (e_yd_class*)pUserWork; + if (!i_this->mLineMatInterpPrevValid || !i_this->mLineMatInterpCurrValid) { + return; + } + const f32 alpha = dusk::frame_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 }; @@ -86,6 +106,17 @@ 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::getSettings().game.enableFrameInterpolation) { + 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::frame_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 9ab6c80e6d..44a8aee249 100644 --- a/src/d/actor/d_a_e_yg.cpp +++ b/src/d/actor/d_a_e_yg.cpp @@ -10,6 +10,8 @@ #include "f_op/f_op_kankyo_mng.h" #include "d/actor/d_a_obj_carry.h" #include "Z2AudioLib/Z2Instances.h" +#include "dusk/frame_interpolation.h" +#include "dusk/settings.h" #include "f_op/f_op_actor_enemy.h" enum E_yg_RES_File_ID { @@ -134,7 +136,26 @@ static BOOL pl_check(e_yg_class* i_this, f32 i_dist) { return FALSE; } -static int daE_YG_Draw(e_yg_class* i_this) { +#if TARGET_PC +static void daE_YG_interp_callback(bool isSimFrame, void* pUserWork) { + e_yg_class* i_this = (e_yg_class*)pUserWork; + if (!i_this->mTentacleInterpPrevValid || !i_this->mTentacleInterpCurrValid) { + return; + } + const f32 alpha = dusk::frame_interp::get_interpolation_step(); + for (int s = 0; s < e_yg_class::TENTACLE_STRAND_COUNT; s++) { + cXyz* dst = i_this->mLineMat.getPos(s); + for (int i = 0; i < e_yg_class::TENTACLE_SEGMENT_COUNT; i++) { + int idx = s * e_yg_class::TENTACLE_SEGMENT_COUNT + i; + const cXyz& p0 = i_this->mTentacleInterpPrev[idx]; + const cXyz& p1 = i_this->mTentacleInterpCurr[idx]; + dst[i] = p0 + (p1 - p0) * alpha; + } + } +} +#endif + +static int daE_YG_Draw(e_yg_class* i_this) { if (i_this->mDispFlag) { return 1; } @@ -160,6 +181,23 @@ static int daE_YG_Draw(e_yg_class* i_this) { color.a = 0xFF; i_this->mLineMat.update(10, color, &actor->tevStr); dComIfGd_set3DlineMatDark(&i_this->mLineMat); + +#if TARGET_PC + if (dusk::getSettings().game.enableFrameInterpolation) { + if (i_this->mTentacleInterpCurrValid) { + memcpy(i_this->mTentacleInterpPrev, i_this->mTentacleInterpCurr, sizeof(i_this->mTentacleInterpCurr)); + i_this->mTentacleInterpPrevValid = true; + } + for (int s = 0; s < e_yg_class::TENTACLE_STRAND_COUNT; s++) { + cXyz* src = i_this->mLineMat.getPos(s); + memcpy(&i_this->mTentacleInterpCurr[s * e_yg_class::TENTACLE_SEGMENT_COUNT], src, + e_yg_class::TENTACLE_SEGMENT_COUNT * sizeof(cXyz)); + } + i_this->mTentacleInterpCurrValid = true; + dusk::frame_interp::add_interpolation_callback(&daE_YG_interp_callback, i_this); + } +#endif + dComIfGd_setList(); return 1; @@ -1378,6 +1416,11 @@ static cPhs_Step daE_YG_Create(fopAc_ac_c* actor) { return cPhs_ERROR_e; } +#if TARGET_PC + i_this->mTentacleInterpPrevValid = false; + i_this->mTentacleInterpCurrValid = false; +#endif + if (!hio_set) { i_this->mIsFirstSpawn = 1; hio_set = true; diff --git a/src/d/actor/d_a_e_yh.cpp b/src/d/actor/d_a_e_yh.cpp index bbbd3e5129..cf9955a7db 100644 --- a/src/d/actor/d_a_e_yh.cpp +++ b/src/d/actor/d_a_e_yh.cpp @@ -12,6 +12,10 @@ #include "f_op/f_op_actor_enemy.h" #include "f_op/f_op_kankyo_mng.h" +#if TARGET_PC +#include "dusk/frame_interpolation.h" +#endif + class daE_YH_HIO_c : public JORReflexible { public: daE_YH_HIO_c(); @@ -85,6 +89,22 @@ 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(bool isSimFrame, void* pUserWork) { + e_yh_class* i_this = (e_yh_class*)pUserWork; + if (!i_this->mLineInterpPrevValid || !i_this->mLineInterpCurrValid) { + return; + } + const f32 alpha = dusk::frame_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; @@ -114,6 +134,17 @@ 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::getSettings().game.enableFrameInterpolation) { + 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::frame_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_obj_fchain.cpp b/src/d/actor/d_a_obj_fchain.cpp index e681fec4e7..024b4ecf8b 100644 --- a/src/d/actor/d_a_obj_fchain.cpp +++ b/src/d/actor/d_a_obj_fchain.cpp @@ -10,6 +10,8 @@ #include "JSystem/J3DGraphBase/J3DDrawBuffer.h" #include "SSystem/SComponent/c_math.h" #include "d/d_com_inf_game.h" +#include "dusk/frame_interpolation.h" +#include "dusk/settings.h" #include static char const l_arcName[] = "Fchain"; @@ -65,6 +67,10 @@ int daObjFchain_c::create() { local_48++; } rv = cPhs_COMPLEATE_e; +#if TARGET_PC + mChainInterpPrevValid = false; + mChainInterpCurrValid = false; +#endif break; } return rv; @@ -289,6 +295,26 @@ void daObjFchain_shape_c::draw() { } } +#if TARGET_PC +static void fchain_interp_callback(bool isSimFrame, void* pUserWork) { + static_cast(pUserWork)->onInterpCallback(); +} + +void daObjFchain_c::onInterpCallback() { + if (!mChainInterpPrevValid || !mChainInterpCurrValid) { + return; + } + + const f32 alpha = dusk::frame_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); @@ -297,6 +323,19 @@ int daObjFchain_c::draw() { return 1; } dComIfGd_getOpaListDark()->entryImm(&mShape, 0); + +#if TARGET_PC + if (dusk::getSettings().game.enableFrameInterpolation) { + if (mChainInterpCurrValid) { + memcpy(mChainInterpPrev, mChainInterpCurr, sizeof(mChainInterpCurr)); + mChainInterpPrevValid = true; + } + + memcpy(mChainInterpCurr, field_0x694, sizeof(mChainInterpCurr)); + mChainInterpCurrValid = true; + dusk::frame_interp::add_interpolation_callback(&fchain_interp_callback, this); + } +#endif } return 1; } diff --git a/src/dusk/ui/editor.cpp b/src/dusk/ui/editor.cpp index 09216a3b8a..469bb920e3 100644 --- a/src/dusk/ui/editor.cpp +++ b/src/dusk/ui/editor.cpp @@ -1881,9 +1881,9 @@ EditorWindow::EditorWindow() { } }); - add_tab("Flags", [this](Rml::Element* content) { - // TODO - }); + //add_tab("Flags", [this](Rml::Element* content) { + // // TODO + //}); add_tab("Minigame", [this](Rml::Element* content) { auto& leftPane = add_child(content, Pane::Type::Controlled); diff --git a/src/dusk/ui/overlay.cpp b/src/dusk/ui/overlay.cpp index 0ce0b904ac..45482230a9 100644 --- a/src/dusk/ui/overlay.cpp +++ b/src/dusk/ui/overlay.cpp @@ -10,6 +10,10 @@ #include #include +#if defined(__APPLE__) +#include +#endif + namespace dusk::ui { namespace { aurora::Module Log{"dusk::ui::overlay"}; @@ -33,7 +37,7 @@ constexpr std::array, 3> kAutoSaveLayers{{ constexpr auto kMenuNotificationDuration = std::chrono::milliseconds(2500); -constexpr std::array kFpsCorners = { "tl", "tr", "bl", "br" }; +constexpr std::array kFpsCorners = {"tl", "tr", "bl", "br"}; Rml::Element* create_toast(Rml::Element* parent, const Toast& toast) { if (toast.type == "autosave") { @@ -130,13 +134,19 @@ Rml::String back_button_name() { return "Back"; } +#if defined(TARGET_ANDROID) || (defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST) +constexpr auto kMenuNotificationPrefix = "3-finger tap or"; +#else +constexpr auto kMenuNotificationPrefix = "Press F1 or"; +#endif + Rml::Element* create_menu_notification(Rml::Element* parent) { auto* elem = append(parent, "toast"); elem->SetClass("menu-notification", true); auto* message = append(elem, "message"); auto* row = append(message, "row"); - append(row, "span")->SetInnerRML("Press F1 or"); + append(row, "span")->SetInnerRML(kMenuNotificationPrefix); auto* icon = append(row, "icon"); icon->SetClass("controller", true); append(row, "span")->SetInnerRML(escape(back_button_name())); @@ -242,7 +252,8 @@ void Overlay::update() { const Uint64 now = SDL_GetPerformanceCounter(); // Limit updates to twice per second - const bool refreshLabel = perfFreq == 0 || mFpsLastUpdate == 0 || + const bool refreshLabel = + perfFreq == 0 || mFpsLastUpdate == 0 || static_cast(now - mFpsLastUpdate) >= 0.5 * static_cast(perfFreq); if (refreshLabel) { mFpsLastUpdate = now; diff --git a/src/m_Do/m_Do_graphic.cpp b/src/m_Do/m_Do_graphic.cpp index 61eaf3bc2d..424f69cf4b 100644 --- a/src/m_Do/m_Do_graphic.cpp +++ b/src/m_Do/m_Do_graphic.cpp @@ -1194,8 +1194,13 @@ static void trimming(view_class* param_0, view_port_class* param_1) { if ((y_orig_pos == 0) && (param_1->scissor.y_orig != param_1->y_orig || (param_1->scissor.height != param_1->height))) { + #if TARGET_PC + f32 sc_top = param_1->scissor.y_orig; + f32 sc_bottom = param_1->scissor.y_orig + param_1->scissor.height; + #else s32 sc_top = (int)param_1->scissor.y_orig; s32 sc_bottom = param_1->scissor.y_orig + param_1->scissor.height; + #endif GXSetNumChans(1); GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE); GXSetNumTexGens(0); @@ -1224,20 +1229,20 @@ static void trimming(view_class* param_0, view_port_class* param_1) { GXLoadPosMtxImm(cMtx_getIdentity(), 0); GXClearVtxDesc(); GXSetVtxDesc(GX_VA_POS, GX_DIRECT); - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, DUSK_IF_ELSE(GX_F32, GX_RGBA4), 0); GXSetProjection(ortho, GX_ORTHOGRAPHIC); GXSetCurrentMtx(0); GXBegin(GX_QUADS, GX_VTXFMT0, 8); #if TARGET_PC - GXPosition3s16(0, 0, -5); - GXPosition3s16(param_1->width, 0, -5); - GXPosition3s16(param_1->width, sc_top, -5); - GXPosition3s16(0, sc_top, -5); - GXPosition3s16(0, sc_bottom, -5); - GXPosition3s16(param_1->width, sc_bottom, -5); - GXPosition3s16(param_1->width, param_1->height, -5); - GXPosition3s16(0, param_1->height, -5); + GXPosition3f32(0, 0, -5); + GXPosition3f32(param_1->width, 0, -5); + GXPosition3f32(param_1->width, sc_top, -5); + GXPosition3f32(0, sc_top, -5); + GXPosition3f32(0, sc_bottom, -5); + GXPosition3f32(param_1->width, sc_bottom, -5); + GXPosition3f32(param_1->width, param_1->height, -5); + GXPosition3f32(0, param_1->height, -5); #else GXPosition3s16(0, 0, -5); GXPosition3s16(FB_WIDTH, 0, -5);