Implement unlocked framerates via interpolation (#315)

* Disable waitForTick and waitBlanking

* Initial frame interpolation implementation

* Initial batch of speed fixes

* Fix Iron Boots

* Strip dead code once used for debugging

* Interpolate shadows

* Revert overzealous/redundant lookups

* Fix JUTFader

* Fix field map cursor

* Fix various particle effects

* Fix Midna when riding Wolf Link

* Fix title logo

* Title Logo 2: Electric Boogaloo

* Fixed grass and flowers

* "Unlock Framerate" config option (WIP)

* Wrap more things in TARGET_PC

* Finish wrapping things in TARGET_PC

* Missed one

* Disable dComIfGd_drawXluListInvisible when interpolating

---------

Co-authored-by: Luke Street <luke@street.dev>
This commit is contained in:
Irastris
2026-04-11 03:06:25 -04:00
committed by GitHub
parent 8c07d8bb8e
commit fb9178cac9
33 changed files with 1039 additions and 147 deletions
+24 -10
View File
@@ -850,7 +850,7 @@ daAlink_FaceTexData const daAlink_c::m_faceTexDataTable[] = {
{dRes_ID_ALANM_BTP_FDAM01_e, dRes_ID_ALANM_BTK_FFINISHA_e},
{dRes_ID_ALANM_BTP_FFINISHA_e, dRes_ID_ALANM_BTK_FFINISHED_e},
{dRes_ID_ALANM_BTP_FARELORD_e, dRes_ID_ALANM_BTK_FARELORD_e},
{dRes_ID_ALANM_BTP_FARELORDTAME_e, dRes_ID_ALANM_BTK_FARELORDTAME_e},
{dRes_ID_ALANM_BTP_FARELORDTAME_e, dRes_ID_ALANM_BTK_FARELORDTAME_e},
{dRes_ID_ALANM_BTP_FPUSHW_e, dRes_ID_ALANM_BTK_FPUSHW_e},
{dRes_ID_ALANM_BTP_FPULLW_e, dRes_ID_ALANM_BTK_FPULLW_e},
{dRes_ID_ALANM_BTP_FWAITST_e, dRes_ID_ALANM_BTK_FWAITST_e},
@@ -1001,7 +1001,7 @@ daAlink_FaceTexData const daAlink_c::m_faceTexDataTable[] = {
{dRes_ID_ALANM_BTP_WL_FSWIMDIEA_e, dRes_ID_ALANM_BTK_WL_FA_e},
{dRes_ID_ALANM_BTP_WL_FSWIMDIEP_e, dRes_ID_ALANM_BTK_WL_FA_e},
{dRes_ID_ALANM_BTP_WL_FMDSHOCK_e, dRes_ID_ALANM_BTK_WL_FMDSHOCK_e},
{dRes_ID_ALANM_BTP_WL_FENTRANCE_e, dRes_ID_ALANM_BTK_WL_FENTRANCE_e},
{dRes_ID_ALANM_BTP_WL_FENTRANCE_e, dRes_ID_ALANM_BTK_WL_FENTRANCE_e},
{dRes_ID_ALANM_BTP_WL_FHOWLC_e, dRes_ID_ALANM_BTK_WL_FA_e},
{dRes_ID_ALANM_BTP_WL_FC_e, dRes_ID_ALANM_BTK_WL_FA_e},
};
@@ -4943,7 +4943,7 @@ int daAlink_c::create() {
if (dComIfG_resLoad(&mShieldPhaseReq, mShieldArcName, mpShieldArcHeap) != cPhs_COMPLEATE_e) {
return cPhs_INIT_e;
}
u32 heapSize = 0x3E930;
heapSize |= 0x80000000;
heapSize |= 0x40000000;
@@ -5885,7 +5885,7 @@ void daAlink_c::setItemMatrix(int param_0) {
|| (mProcID == PROC_CUT_REVERSE && mProcVar2.field_0x300c != 0)
|| mProcID == PROC_GUARD_BREAK
|| (mEquipItem == 0x103 && !checkEndResetFlg1(ERFLG1_SHIELD_BACKBONE) && !checkModeFlg(0x400))
)
)
{
mShieldModel->setBaseTRMtx(mpLinkModel->getAnmMtx(mRightItemJntNo));
@@ -5949,9 +5949,23 @@ void daAlink_c::setItemMatrix(int param_0) {
mpLinkBootModels[0]->setAnmMtx(3, mpLinkModel->getAnmMtx(0x15));
mDoMtx_stack_c::XrotS(-0x8000);
mDoMtx_concat(mpLinkModel->getAnmMtx(0x18), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(1));
mDoMtx_concat(mpLinkModel->getAnmMtx(0x19), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(2));
mDoMtx_concat(mpLinkModel->getAnmMtx(0x1A), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(3));
#ifdef TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
Mtx boot_mtx;
mDoMtx_concat(mpLinkModel->getAnmMtx(0x18), mDoMtx_stack_c::get(), boot_mtx);
mpLinkBootModels[1]->setAnmMtx(1, boot_mtx);
mDoMtx_concat(mpLinkModel->getAnmMtx(0x19), mDoMtx_stack_c::get(), boot_mtx);
mpLinkBootModels[1]->setAnmMtx(2, boot_mtx);
mDoMtx_concat(mpLinkModel->getAnmMtx(0x1A), mDoMtx_stack_c::get(), boot_mtx);
mpLinkBootModels[1]->setAnmMtx(3, boot_mtx);
} else {
#endif
mDoMtx_concat(mpLinkModel->getAnmMtx(0x18), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(1));
mDoMtx_concat(mpLinkModel->getAnmMtx(0x19), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(2));
mDoMtx_concat(mpLinkModel->getAnmMtx(0x1A), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(3));
#ifdef TARGET_PC
}
#endif
}
if (!checkNoResetFlg2(FLG2_STATUS_WINDOW_DRAW)) {
@@ -6279,7 +6293,7 @@ void daAlink_c::setWolfAtCollision() {
void daAlink_c::resetAtCollision(BOOL param_0) {
if (checkNoResetFlg0(FLG0_CUT_AT_FLG)) {
if (param_0
if (param_0
&& !setSwordHitVibration(&mAtCps[0])
&& !setSwordHitVibration(&mAtCps[1])
&& !setSwordHitVibration(&mAtCps[2])
@@ -14055,7 +14069,7 @@ void daAlink_c::setMetamorphoseModel(BOOL i_isChangeToWolf) {
JKRHeap* heap = setItemHeap();
mHeldItemModel = initModel(loadAramBmd(dRes_ID_ALANM_BMD_AL_WF_e, 0x6000), 0);
if (!mItemBck.init(bck, FALSE, 2, 1.0f, 0, -1, false)) {
JUT_ASSERT(20842, FALSE);
}
@@ -16727,7 +16741,7 @@ int daAlink_c::procAutoJump() {
#if VERSION == VERSION_SHIELD_DEBUG
if (!checkStageName("F_SP115") && mGrabItemAcKeep.getActor() != NULL) {
if ((fopAcM_GetName(mGrabItemAcKeep.getActor()) == fpcNm_NI_e && ((ni_class*)mGrabItemAcKeep.getActor())->checkGold() != TRUE) ||
(fopAcM_GetName(mGrabItemAcKeep.getActor()) == fpcNm_NPC_TKJ2_e))
(fopAcM_GetName(mGrabItemAcKeep.getActor()) == fpcNm_NPC_TKJ2_e))
{
mMaxSpeed = mpHIO->mAutoJump.m.mCuccoJumpMaxSpeed;
field_0x3478 = mpHIO->mAutoJump.m.mCuccoFallMaxSpeed;
+7
View File
@@ -14,6 +14,7 @@
#include "d/d_msg_object.h"
#include "d/d_s_play.h"
#include "d/d_debug_viewer.h"
#include "dusk/frame_interpolation.h"
static f32 dummy_lit_3777(int idx, u8 foo) {
Vec dummy_vec = {0.0f, 0.0f, 0.0f};
@@ -1052,6 +1053,12 @@ void daMidna_c::setBodyPartMatrix() {
mpModel->setAnmMtx(i, mpShadowModel->getAnmMtx(i));
}
mpModel->calcWeightEnvelopeMtx();
#ifdef TARGET_PC
// Frame interpolation: Record weight envelopes for Midna here, as they are otherwise missed causing distortion
for (u16 i = 0; i < mpModel->getModelData()->getWEvlpMtxNum(); i++) {
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(mpModel->getWeightAnmMtx(i)), mpModel->getWeightAnmMtx(i));
}
#endif
}
mDoMtx_stack_c::transS(mpShadowModel->getAnmMtx(JNT_BACKBONE1)[0][3],
+13 -7
View File
@@ -122,7 +122,7 @@ static procFunc daTitleProc[6] = {
int daTitle_c::create() {
fopAcM_ct(this, daTitle_c);
int phase_state = dComIfG_resLoad(&mPhaseReq, l_arcName);
if (phase_state != cPhs_COMPLEATE_e) {
return phase_state;
@@ -152,15 +152,21 @@ int daTitle_c::createHeapCallBack(fopAc_ac_c* actor) {
}
int daTitle_c::Execute() {
#if PLATFORM_WII || PLATFORM_SHIELD
#if PLATFORM_WII || PLATFORM_SHIELD
mDoGph_gInf_c::resetDimming();
#endif
#endif
if (fopOvlpM_IsPeek()) {
return 1;
}
dMenu_Collect3D_c::setViewPortOffsetY(0.0f);
#ifdef TARGET_PC
if (!dusk::getSettings().game.enableFrameInterpolation) {
#endif
dMenu_Collect3D_c::setViewPortOffsetY(0.0f);
#ifdef TARGET_PC
}
#endif
if (mDoRst::isReset()) {
return 1;
@@ -169,9 +175,9 @@ int daTitle_c::Execute() {
(this->*daTitleProc[mProcID])();
KeyWaitAnm();
#if VERSION == VERSION_SHIELD_DEBUG
#if VERSION == VERSION_SHIELD_DEBUG
KeyWaitPosMove();
#endif
#endif
return 1;
}
@@ -390,7 +396,7 @@ int daTitle_c::Delete() {
dComIfG_resDelete(&mPhaseReq, l_arcName);
JKR_DELETE(mTitle.Scr);
JKR_DELETE(field_0x600);
mpMount->getArchive()->removeResourceAll();
JKRUnmountArchive(mpMount->getArchive());
mpMount->destroy();
+25 -2
View File
@@ -5,6 +5,8 @@
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
#include "SSystem/SComponent/c_counter.h"
#include "dusk/frame_interpolation.h"
#if TARGET_PC
const u16 l_J_Ohana00_64TEX__width = 64;
const u16 l_J_Ohana00_64TEX__height = 64;
@@ -695,7 +697,16 @@ void dFlower_packet_c::draw() {
GXSetChanAmbColor(GX_COLOR0A0, sp64);
if (!cLib_checkBit<u8>(sp44->m_state, 4) && !cLib_checkBit<u8>(sp44->m_state, 0x40)) {
GXLoadPosMtxImm(sp44->m_modelMtx, 0);
#ifdef TARGET_PC
Mtx flower_mtx;
if (dusk::frame_interp::lookup_replacement(reinterpret_cast<const void*>(&sp44->m_modelMtx), flower_mtx)) {
GXLoadPosMtxImm(flower_mtx, 0);
} else {
#endif
GXLoadPosMtxImm(sp44->m_modelMtx, 0);
#ifdef TARGET_PC
}
#endif
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
#if TARGET_PC
@@ -841,7 +852,16 @@ void dFlower_packet_c::draw() {
sp30++;
if (!cLib_checkBit<u8>(sp34->m_state, 4) && cLib_checkBit<u8>(sp34->m_state, 0x40)) {
GXLoadPosMtxImm(sp34->m_modelMtx, 0);
#ifdef TARGET_PC
Mtx flower_mtx;
if (dusk::frame_interp::lookup_replacement(reinterpret_cast<const void*>(&sp34->m_modelMtx), flower_mtx)) {
GXLoadPosMtxImm(flower_mtx, 0);
} else {
#endif
GXLoadPosMtxImm(sp34->m_modelMtx, 0);
#ifdef TARGET_PC
}
#endif
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
#if TARGET_PC
@@ -973,6 +993,9 @@ void dFlower_packet_c::update() {
mDoMtx_stack_c::copy(temp_r28);
mDoMtx_stack_c::scaleM(temp_f31, temp_f31, temp_f31);
cMtx_concat(j3dSys.getViewMtx(), temp_r28, data_p->m_modelMtx);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(&data_p->m_modelMtx), data_p->m_modelMtx);
#endif
}
}
+15 -1
View File
@@ -11,6 +11,8 @@
#include "d/d_camera.h"
#include "f_op/f_op_camera_mng.h"
#include "dusk/frame_interpolation.h"
const u16 l_M_Hijiki00TEX__width = 31;
const u16 l_M_Hijiki00TEX__height = 31;
const u16 l_M_kusa05_RGBATEX__width = 31;
@@ -751,7 +753,16 @@ void dGrass_packet_c::draw() {
GXSetChanAmbColor(GX_COLOR0A0, sp38);
if (!cLib_checkBit<u8>(var_r29->field_0x01, 2)) {
GXLoadPosMtxImm(var_r29->m_modelMtx, 0);
#ifdef TARGET_PC
Mtx grass_mtx;
if (dusk::frame_interp::lookup_replacement(reinterpret_cast<const void*>(&var_r29->m_modelMtx), grass_mtx)) {
GXLoadPosMtxImm(grass_mtx, 0);
} else {
#endif
GXLoadPosMtxImm(var_r29->m_modelMtx, 0);
#ifdef TARGET_PC
}
#endif
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
if (var_r29->field_0x05 <= 3 || var_r29->field_0x05 >= 10) {
if (var_r29->field_0x02 < -1) {
@@ -1006,6 +1017,9 @@ void dGrass_packet_c::update() {
mDoMtx_stack_c::scaleM(scale, scale, scale);
cMtx_concat(j3dSys.getViewMtx(), mDoMtx_stack_c::get(), data_p->m_modelMtx);
}
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(&data_p->m_modelMtx), data_p->m_modelMtx);
#endif
}
}
data_p++;
+8 -3
View File
@@ -20,6 +20,7 @@
#include "m_Do/m_Do_controller_pad.h"
#include "m_Do/m_Do_graphic.h"
#include "m_Do/m_Do_lib.h"
#include "dusk/frame_interpolation.h"
#include <cmath>
#include <cstring>
@@ -11030,16 +11031,20 @@ static int camera_draw(camera_process_class* i_this) {
int trim_height = body->TrimHeight();
#if TARGET_PC
#if TARGET_PC
trim_height *= viewport->height / FB_HEIGHT;
window->setScissor(0.0f, trim_height, viewport->width, viewport->height - trim_height * 2.0f);
#else
#else
window->setScissor(0.0f, trim_height, FB_WIDTH, FB_HEIGHT - trim_height * 2.0f);
#endif
#endif
C_MTXPerspective(process->view.projMtx, process->view.fovy, process->view.aspect, process->view.near_, process->view.far_);
mDoMtx_lookAt(process->view.viewMtx, &process->view.lookat.eye, &process->view.lookat.center,
&process->view.lookat.up, process->view.bank);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(process->view.viewMtx),
process->view.viewMtx);
#endif
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomProjection(process->view.projMtx);
+49 -4
View File
@@ -11,6 +11,7 @@
#include "d/d_com_inf_game.h"
#include "d/d_drawlist.h"
#include "d/d_s_play.h"
#include "dusk/frame_interpolation.h"
#include "dusk/gx_helper.h"
#include "dusk/logging.h"
#include "m_Do/m_Do_graphic.h"
@@ -1089,7 +1090,16 @@ void dDlst_shadowReal_c::draw() {
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXSetCurrentMtx(GX_PNMTX0);
GXLoadTexMtxImm(mReceiverProjMtx, GX_TEXMTX0, GX_MTX3x4);
#ifdef TARGET_PC
Mtx receiver_proj_mtx;
if (dusk::frame_interp::lookup_replacement(&mReceiverProjMtx, receiver_proj_mtx)) {
GXLoadTexMtxImm(receiver_proj_mtx, GX_TEXMTX0, GX_MTX3x4);
} else {
#endif
GXLoadTexMtxImm(mReceiverProjMtx, GX_TEXMTX0, GX_MTX3x4);
#ifdef TARGET_PC
}
#endif
mShadowRealPoly.draw();
}
@@ -1247,6 +1257,10 @@ u8 dDlst_shadowReal_c::setShadowRealMtx(cXyz* param_0, cXyz* param_1, f32 param_
C_MTXOrtho(mRenderProjMtx, param_2, -param_2, -param_2, param_2, 1.0f, 10000.0f);
C_MTXLightOrtho(mReceiverProjMtx, param_2, -param_2, -param_2, param_2, 0.5f, -0.5f, 0.5f, 0.5f);
cMtx_concat(mReceiverProjMtx, mViewMtx, mReceiverProjMtx);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(&mViewMtx, mViewMtx);
dusk::frame_interp::record_final_mtx_raw(&mReceiverProjMtx, mReceiverProjMtx);
#endif
return r29;
}
@@ -1309,13 +1323,31 @@ void dDlst_shadowSimple_c::draw() {
GXSetTevColor(GX_TEVREG0, l_color);
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
GXLoadPosMtxImm(mVolumeMtx, GX_PNMTX0);
#ifdef TARGET_PC
Mtx volume_mtx;
if (dusk::frame_interp::lookup_replacement(&mVolumeMtx, volume_mtx)) {
GXLoadPosMtxImm(volume_mtx, GX_PNMTX0);
} else {
#endif
GXLoadPosMtxImm(mVolumeMtx, GX_PNMTX0);
#ifdef TARGET_PC
}
#endif
GXSetCurrentMtx(GX_PNMTX0);
GXCallDisplayList(l_frontMat, 0x40);
GXCallDisplayList(l_shadowVolumeDL, 0x40);
GXCallDisplayList(l_backSubMat, 0x20);
GXCallDisplayList(l_shadowVolumeDL, 0x40);
GXLoadPosMtxImm(mMtx, GX_PNMTX1);
#ifdef TARGET_PC
Mtx shadow_mtx;
if (dusk::frame_interp::lookup_replacement(&mMtx, shadow_mtx)) {
GXLoadPosMtxImm(shadow_mtx, GX_PNMTX1);
} else {
#endif
GXLoadPosMtxImm(mMtx, GX_PNMTX1);
#ifdef TARGET_PC
}
#endif
GXSetCurrentMtx(GX_PNMTX1);
if (mpTexObj != NULL) {
@@ -1394,6 +1426,10 @@ void dDlst_shadowSimple_c::set(cXyz* param_0, f32 param_1, f32 param_2, cXyz* pa
mDoMtx_stack_c::YrotM(param_4);
mDoMtx_stack_c::scaleM(param_2, 1.0f, param_2 * param_5);
cMtx_concat(j3dSys.getViewMtx(), mDoMtx_stack_c::get(), mMtx);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(&mVolumeMtx, mVolumeMtx);
dusk::frame_interp::record_final_mtx_raw(&mMtx, mMtx);
#endif
mpTexObj = param_6;
}
@@ -1541,7 +1577,16 @@ void dDlst_shadowControl_c::draw(Mtx param_0) {
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX0);
GXSetNumTevStages(1);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXLoadPosMtxImm(param_0, GX_PNMTX0);
#ifdef TARGET_PC
Mtx draw_mtx;
if (dusk::frame_interp::lookup_replacement(param_0, draw_mtx)) {
GXLoadPosMtxImm(draw_mtx, GX_PNMTX0);
} else {
#endif
GXLoadPosMtxImm(param_0, GX_PNMTX0);
#ifdef TARGET_PC
}
#endif
GXColor matColor = {0, 0, 0, 0x20};
GXSetChanMatColor(GX_ALPHA0, matColor);
+10 -3
View File
@@ -17,6 +17,7 @@
#include "d/d_msg_scrn_explain.h"
#include "m_Do/m_Do_graphic.h"
#include "d/actor/d_a_midna.h"
#include "dusk/frame_interpolation.h"
#include <cstring>
dMenu_Fmap2DBack_c::dMenu_Fmap2DBack_c() {
@@ -390,11 +391,17 @@ void dMenu_Fmap2DBack_c::draw() {
(mArrowPos3DZ + control_ypos + fVar3) - fVar5, &mArrowPos2DX,
&mArrowPos2DY);
field_0x11e0 -= g_fmapHIO.mCursorSpeed;
#ifdef TARGET_PC
for (u32 i = 0; i < dusk::frame_interp::get_presentation_ui_advance_ticks(); ++i) {
#endif
field_0x11e0 -= g_fmapHIO.mCursorSpeed;
if (field_0x11e0 < 0.0f) {
field_0x11e0 += 360.0f;
if (field_0x11e0 < 0.0f) {
field_0x11e0 += 360.0f;
}
#ifdef TARGET_PC
}
#endif
mpPointParent->getPanePtr()->rotate(mpPointParent->getSizeX() / 2.0f,
mpPointParent->getSizeY() / 2.0f, ROTATE_Z,
+53 -34
View File
@@ -20,6 +20,7 @@
#include "d/d_msg_class.h"
#include "d/d_msg_object.h"
#include "d/d_pane_class.h"
#include "dusk/frame_interpolation.h"
#include <cstring>
dMeter2Draw_c::dMeter2Draw_c(JKRExpHeap* mp_heap) {
@@ -636,38 +637,49 @@ void dMeter2Draw_c::draw() {
if (field_0x756 >= 0) {
var_f29 = g_drawHIO.mLightDrop.mDropPikariAnimSpeed_Completed;
int temp_r5_2 = g_drawHIO.mLightDrop.mPikariInterval * 15;
#ifdef TARGET_PC
// Set even if not advancing
var_f28 = g_drawHIO.mLightDrop.mPikariScaleComplete;
if (field_0x756 <= temp_r5_2) {
int temp_r4 = (field_0x756 % g_drawHIO.mLightDrop.mPikariInterval);
int temp_r3_5 = field_0x756 / g_drawHIO.mLightDrop.mPikariInterval;
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
if (field_0x756 <= temp_r5_2) {
int temp_r4 = (field_0x756 % g_drawHIO.mLightDrop.mPikariInterval);
int temp_r3_5 = field_0x756 / g_drawHIO.mLightDrop.mPikariInterval;
if (temp_r4 == 0 && field_0x62c[temp_r3_5] == 0.0f) {
field_0x62c[temp_r3_5] = 18.0f;
}
var_f28 = g_drawHIO.mLightDrop.mPikariScaleComplete;
field_0x756++;
} else {
int temp_r5_3 = temp_r5_2 + 1;
if (field_0x756 == temp_r5_3) {
if (field_0x62c[15] == 0.0f) {
field_0x756++;
if (temp_r4 == 0 && field_0x62c[temp_r3_5] == 0.0f) {
field_0x62c[temp_r3_5] = 18.0f;
}
var_f28 = g_drawHIO.mLightDrop.mPikariScaleComplete;
} else if (field_0x756 >= g_drawHIO.mLightDrop.field_0x54 + temp_r5_3) {
for (int i = 0; i < 16; i++) {
field_0x62c[i] = 18.0f - var_f29;
field_0x66c[i] = 18.0f - g_drawHIO.mLightDrop.mPikariLoopAnimSpeed;
}
field_0x756 = -1;
} else {
field_0x756++;
} else {
int temp_r5_3 = temp_r5_2 + 1;
if (field_0x756 == temp_r5_3) {
if (field_0x62c[15] == 0.0f) {
field_0x756++;
}
var_f28 = g_drawHIO.mLightDrop.mPikariScaleComplete;
} else if (field_0x756 >= g_drawHIO.mLightDrop.field_0x54 + temp_r5_3) {
for (int i = 0; i < 16; i++) {
field_0x62c[i] = 18.0f - var_f29;
field_0x66c[i] = 18.0f - g_drawHIO.mLightDrop.mPikariLoopAnimSpeed;
}
field_0x756 = -1;
#ifdef TARGET_PC
break;
#endif
} else {
field_0x756++;
}
}
}
#ifdef TARGET_PC
}
#endif
for (int i = 0; i < 16; i++) {
if (field_0x66c[i] > 0.0f) {
@@ -1336,20 +1348,27 @@ void dMeter2Draw_c::drawPikari(f32 i_posX, f32 i_posY, f32* i_framep, f32 i_scal
if (param_9 != 3 && param_9 != 4 && param_9 != 5 && dMsgObject_isTalkNowCheck()) {
*i_framep = 0.0f;
} else {
*i_framep += param_8;
if (*i_framep > var_f31) {
if (param_9 == 1 || param_9 == 2 || param_9 == 3) {
*i_framep = 18.0f;
} else {
*i_framep = 0.0f;
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 i = 0; i < ui_advance_ticks; ++i) {
#endif
*i_framep += param_8;
if (*i_framep > var_f31) {
if (param_9 == 1 || param_9 == 2 || param_9 == 3) {
*i_framep = 18.0f;
} else {
*i_framep = 0.0f;
}
}
}
if (*i_framep == 18.0f && param_9 == 1) {
mDoAud_seStart(Z2SE_NAVI_BLINK, NULL, 0, 0);
} else if (*i_framep == 18.0f && param_9 == 2) {
mDoAud_seStart(Z2SE_SY_ITEM_COMBINE_ICON, NULL, 0, 0);
if (*i_framep == 18.0f && param_9 == 1) {
mDoAud_seStart(Z2SE_NAVI_BLINK, NULL, 0, 0);
} else if (*i_framep == 18.0f && param_9 == 2) {
mDoAud_seStart(Z2SE_SY_ITEM_COMBINE_ICON, NULL, 0, 0);
}
#ifdef TARGET_PC
}
#endif
playPikariBckAnimation(*i_framep);
playPikariBpkAnimation(*i_framep);
+21 -6
View File
@@ -6,6 +6,7 @@
#include "JSystem/J2DGraph/J2DScreen.h"
#include "d/d_com_inf_game.h"
#include "d/d_pane_class.h"
#include "dusk/frame_interpolation.h"
class dMsgScrnLight_HIO_c {
public:
@@ -202,10 +203,17 @@ void dMsgScrnLight_c::draw(f32* i_anmFrame, f32 i_posX, f32 i_posY, f32 i_scaleX
}
if (mPlayAnim) {
*i_anmFrame += 1.0f;
if (*i_anmFrame >= mpBck->getFrameMax()) {
*i_anmFrame = 0.0f;
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 i = 0; i < ui_advance_ticks; ++i) {
#endif
*i_anmFrame += 1.0f;
if (*i_anmFrame >= mpBck->getFrameMax()) {
*i_anmFrame = 0.0f;
}
#ifdef TARGET_PC
}
#endif
mBckFrame = *i_anmFrame;
mBpkFrame = *i_anmFrame;
@@ -220,11 +228,18 @@ void dMsgScrnLight_c::draw(f32* i_anmFrame, f32 i_posX, f32 i_posY, f32 i_scaleX
mpParent_c->setBlackWhite(i_black, i_white);
if (mPlayAnim) {
*i_anmFrame += i_anmRate;
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 i = 0; i < ui_advance_ticks; ++i) {
#endif
*i_anmFrame += i_anmRate;
if (*i_anmFrame >= mpBck->getFrameMax()) {
*i_anmFrame = 0.0f;
if (*i_anmFrame >= mpBck->getFrameMax()) {
*i_anmFrame = 0.0f;
}
#ifdef TARGET_PC
}
#endif
mBckFrame = *i_anmFrame;
mBpkFrame = *i_anmFrame;
+48 -19
View File
@@ -5,6 +5,7 @@
#include "d/d_com_inf_game.h"
#include "JSystem/J2DGraph/J2DAnimation.h"
#include "JSystem/J2DGraph/J2DAnmLoader.h"
#include "dusk/frame_interpolation.h"
#include <cstring>
dSelect_cursorHIO_c::dSelect_cursorHIO_c() {
@@ -270,15 +271,22 @@ void dSelect_cursor_c::update() {
if (mUpdateFlag) {
if (field_0x30) {
if (chkPlayAnime(0)) {
if (mNameIdx == 1) {
field_0x44 += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x44 += fVar1;
}
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
if (mNameIdx == 1) {
field_0x44 += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x44 += fVar1;
}
if (field_0x44 >= field_0x30->getFrameMax()) {
field_0x44 -= field_0x30->getFrameMax();
if (field_0x44 >= field_0x30->getFrameMax()) {
field_0x44 -= field_0x30->getFrameMax();
}
#ifdef TARGET_PC
}
#endif
field_0x30->setFrame(field_0x44);
setBpkAnimation(field_0x30);
@@ -294,14 +302,21 @@ void dSelect_cursor_c::update() {
for (int i = 0; i < 2; i++) {
if (field_0x34[i]) {
if ((i == 0 && chkPlayAnime(2)) || (i == 1 && chkPlayAnime(3))) {
if (mNameIdx == 1) {
field_0x48[i] += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x48[i] += fVar1;
}
if (field_0x48[i] >= field_0x34[i]->getFrameMax()) {
field_0x48[i] -= field_0x34[i]->getFrameMax();
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
if (mNameIdx == 1) {
field_0x48[i] += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x48[i] += fVar1;
}
if (field_0x48[i] >= field_0x34[i]->getFrameMax()) {
field_0x48[i] -= field_0x34[i]->getFrameMax();
}
#ifdef TARGET_PC
}
#endif
field_0x34[i]->setFrame(field_0x48[i]);
}
@@ -310,7 +325,11 @@ void dSelect_cursor_c::update() {
}
if (field_0x2C && chkPlayAnime(1)) {
if (mNameIdx == 1) {
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
if (mNameIdx == 1) {
field_0x40 += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x40 += fVar1;
@@ -318,14 +337,24 @@ void dSelect_cursor_c::update() {
if (field_0x40 >= field_0x2C->getFrameMax()) {
field_0x40 -= field_0x2C->getFrameMax();
}
field_0x2C->setFrame(field_0x40);
setBckAnimation(field_0x2C);
#ifdef TARGET_PC
}
#endif
field_0x2C->setFrame(field_0x40);
setBckAnimation(field_0x2C);
}
if (chkPlayAnime(1) && mNameIdx == 0) {
setCursorAnimation();
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
setCursorAnimation();
#ifdef TARGET_PC
}
#endif
}
mpScreen->animation();
+18 -8
View File
@@ -2,21 +2,31 @@
#include "d/d_select_icon.h"
#include "JSystem/J2DGraph/J2DAnimation.h"
#include "dusk/frame_interpolation.h"
dSi_HIO_c::dSi_HIO_c() {}
void dSelect_icon_c::animation() {
if (field_0x10->getAlpha() != 0) {
field_0x20 += field_0x2c;
if (field_0x20 >= field_0x1c->getFrameMax()) {
field_0x20 = 0.0f;
}
field_0x1c->setFrame(field_0x20);
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 i = 0; i < ui_advance_ticks; ++i) {
#endif
field_0x20 += field_0x2c;
if (field_0x20 >= field_0x1c->getFrameMax()) {
field_0x20 = 0.0f;
}
field_0x1c->setFrame(field_0x20);
field_0x28 += field_0x2c;
if (field_0x28 >= field_0x24->getFrameMax()) {
field_0x28 = 0.0f;
field_0x28 += field_0x2c;
if (field_0x28 >= field_0x24->getFrameMax()) {
field_0x28 = 0.0f;
}
#ifdef TARGET_PC
}
// Set even if not advancing
field_0x1c->setFrame(field_0x20);
#endif
field_0x24->setFrame(field_0x28);
field_0x8->animation();