Delta time pane scale/color/alpha

This commit is contained in:
Irastris
2026-08-16 13:32:00 -04:00
parent 89480a520f
commit f8ef48d74e
7 changed files with 216 additions and 12 deletions
+21 -4
View File
@@ -4,6 +4,10 @@
#include "JSystem/JUtility/TColor.h"
#include "d/d_pane_class_alpha.h"
#if TARGET_PC
#include <utility>
#endif
class JKRHeap;
void dPaneClass_showNullPane(J2DScreen*);
@@ -26,6 +30,9 @@ public:
void setBlackWhite(JUtility::TColor, JUtility::TColor);
void paneTrans(f32, f32);
void paneScale(f32, f32);
#if TARGET_PC
void presentAnime();
#endif
bool scaleAnime(s16, f32, f32, u8);
bool colorAnime(s16, JUtility::TColor, JUtility::TColor, JUtility::TColor,
JUtility::TColor, u8);
@@ -54,8 +61,14 @@ public:
void resize(f32 x, f32 y) { getPanePtr()->resize(x, y); }
void move(f32 x, f32 y) { getPanePtr()->move(x, y); }
void scaleAnimeStart(s16 v) { mScaleAnime = v; }
void colorAnimeStart(s16 start) { mColorAnime = start; }
void scaleAnimeStart(DUSK_IF_ELSE(f32, s16) v) {
mScaleAnime = v;
IF_DUSK(mScaleAnimation.active = false;)
}
void colorAnimeStart(DUSK_IF_ELSE(f32, s16) start) {
mColorAnime = start;
IF_DUSK(mColorAnimation.active = false;)
}
f32 getPosX() { return getPanePtr()->getBounds().i.x; }
f32 getPosY() { return getPanePtr()->getBounds().i.y; }
@@ -106,10 +119,14 @@ public:
/* 0x5C */ JUtility::TColor mInitBlack;
/* 0x60 */ s16 field_0x60;
/* 0x62 */ s16 field_0x62;
/* 0x64 */ s16 mScaleAnime;
/* 0x64 */ DUSK_IF_ELSE(f32, s16) mScaleAnime;
/* 0x66 */ s16 field_0x66;
/* 0x68 */ s16 field_0x68;
/* 0x6A */ s16 mColorAnime;
/* 0x6A */ DUSK_IF_ELSE(f32, s16) mColorAnime;
#if TARGET_PC
Animation<f32> mScaleAnimation;
Animation<std::pair<JUtility::TColor, JUtility::TColor>> mColorAnimation;
#endif
};
#endif /* D_PANE_D_PANE_CLASS_H */
+23 -4
View File
@@ -9,6 +9,16 @@ class JKRExpHeap;
class CPaneMgrAlpha {
public:
#if TARGET_PC
template <typename T>
struct Animation {
bool active = false;
s16 duration;
u8 curve;
T start, end;
};
#endif
virtual ~CPaneMgrAlpha();
virtual void setAlpha(u8);
@@ -18,9 +28,12 @@ public:
void show();
void hide();
bool isVisible();
f32 rateCalc(s16, s16, u8);
f32 rateCalc(DUSK_IF_ELSE(f32, s16), DUSK_IF_ELSE(f32, s16), u8);
void setAlphaRate(f32);
f32 getAlphaRate();
#if TARGET_PC
void presentAlphaAnime();
#endif
bool alphaAnime(s16 timer, u8 startAlpha, u8 endAlpha, u8 calcType);
bool alphaAnimeLoop(s16, u8, u8, u8);
void childPaneCount(J2DPane*);
@@ -29,8 +42,11 @@ public:
J2DPane* getPanePtr() { return mPane; }
u8 getAlpha() { return getPanePtr()->getAlpha(); }
s16 getAlphaTimer() { return mAlphaTimer; }
void alphaAnimeStart(s16 start) { mAlphaTimer = start; }
DUSK_IF_ELSE(f32, s16) getAlphaTimer() { return mAlphaTimer; }
void alphaAnimeStart(DUSK_IF_ELSE(f32, s16) start) {
mAlphaTimer = start;
IF_DUSK(mAlphaAnimation.active = false;)
}
u8 getInitAlpha() { return mInitAlpha; }
/* 0x04 */ J2DPane* mPane;
@@ -38,9 +54,12 @@ public:
/* 0x0C */ void* mpFirstStackAlpha;
/* 0x10 */ u8* field_0x10;
/* 0x14 */ s16 mChildPaneCount;
/* 0x16 */ s16 mAlphaTimer;
/* 0x16 */ DUSK_IF_ELSE(f32, s16) mAlphaTimer;
/* 0x18 */ u8 mInitAlpha;
/* 0x19 */ u8 mFlags;
#if TARGET_PC
Animation<u8> mAlphaAnimation;
#endif
};
class CPaneMgrAlphaMorf : public CPaneMgrAlpha {
+7
View File
@@ -19,6 +19,7 @@
#include "m_Do/m_Do_graphic.h"
#if TARGET_PC
#include "dusk/game_clock.h"
#include "dusk/interp/frame_interpolation.h"
#include "dusk/version.hpp"
#endif
@@ -380,6 +381,12 @@ int daTitle_c::getDemoPrm() {
}
int daTitle_c::Draw() {
#if TARGET_PC
if (field_0x600 != NULL && dusk::game_clock::is_presentation_frame()) {
field_0x600->presentAlphaAnime();
}
#endif
J3DModelData* modelData = mpModel->getModelData();
cMtx_trans(mpModel->getBaseTRMtx(), IREG_F(7), IREG_F(8), IREG_F(9) + -430.0f);
mpModel->getBaseScale()->x = -1.0f;
+55 -1
View File
@@ -13,7 +13,16 @@
#include "m_Do/m_Do_ext.h"
#include "m_Do/m_Do_graphic.h"
#if TARGET_PC
#include "dusk/interp/lerp.h"
#include "dusk/interp/user_interface.h"
#endif
CPaneMgr::CPaneMgr() {
#if TARGET_PC
mScaleAnimation.active = false;
mColorAnimation.active = false;
#endif
mpFirstStackAlpha = NULL;
mpFirstStackSize = NULL;
}
@@ -45,6 +54,12 @@ void CPaneMgr::setAlpha(u8 alpha) {
}
void CPaneMgr::reinit() {
#if TARGET_PC
mAlphaAnimation.active = false;
mScaleAnimation.active = false;
mColorAnimation.active = false;
#endif
mInitPos.x = getPanePtr()->getBounds().i.x;
mInitPos.y = getPanePtr()->getBounds().i.y;
@@ -66,6 +81,12 @@ void CPaneMgr::reinit() {
}
void CPaneMgr::initiate(J2DPane* p_pane, JKRExpHeap* p_heap) {
#if TARGET_PC
mAlphaAnimation.active = false;
mScaleAnimation.active = false;
mColorAnimation.active = false;
#endif
mPane = p_pane;
if (p_heap) {
@@ -269,7 +290,29 @@ void CPaneMgr::paneScale(f32 x, f32 y) {
}
}
#if TARGET_PC
void CPaneMgr::presentAnime() {
presentAlphaAnime();
dusk::vdt::present_animation(mScaleAnimation, mScaleAnime, *this, [&](f32 rate) {
const f32 scale = dusk::interp::lerp(mScaleAnimation.start, mScaleAnimation.end, rate);
getPanePtr()->scale(getInitScaleX() * scale, getInitScaleY() * scale);
});
dusk::vdt::present_animation(mColorAnimation, mColorAnime, *this, [&](f32 rate) {
setBlackWhite(
dusk::interp::lerp(mColorAnimation.start.first, mColorAnimation.end.first, rate),
dusk::interp::lerp(mColorAnimation.start.second, mColorAnimation.end.second, rate));
});
}
#endif
bool CPaneMgr::scaleAnime(s16 param_0, f32 param_1, f32 param_2, u8 param_3) {
#if TARGET_PC
if (!dusk::vdt::request_animation(mScaleAnimation, mScaleAnime, param_0, param_1, param_2, param_3)) {
return false;
}
getPanePtr()->scale(mInitScale.x * param_2, mInitScale.y * param_2);
return true;
#else
if (mScaleAnime < param_0 - 1) {
mScaleAnime++;
f32 rate = rateCalc(param_0, mScaleAnime, param_3);
@@ -281,10 +324,20 @@ bool CPaneMgr::scaleAnime(s16 param_0, f32 param_1, f32 param_2, u8 param_3) {
return true;
}
return false;
#endif
}
bool CPaneMgr::colorAnime(s16 anmTimer, JUtility::TColor startBlack, JUtility::TColor endBlack,
JUtility::TColor startWhite, JUtility::TColor endWhite, u8 calcType) {
JUtility::TColor startWhite, JUtility::TColor endWhite, u8 calcType) {
#if TARGET_PC
if (!dusk::vdt::request_animation(mColorAnimation, mColorAnime, anmTimer,
{startBlack, startWhite}, {endBlack, endWhite}, calcType))
{
return false;
}
setBlackWhite(endBlack, endWhite);
return true;
#else
if (mColorAnime < anmTimer - 1) {
mColorAnime++;
f32 rate = rateCalc(anmTimer, mColorAnime, calcType);
@@ -349,6 +402,7 @@ bool CPaneMgr::colorAnime(s16 anmTimer, JUtility::TColor startBlack, JUtility::T
}
return false;
#endif
}
Vec CPaneMgr::getGlobalVtx(J2DPane* p_pane, Mtx* param_1, u8 param_2, bool param_3,
+47 -3
View File
@@ -5,7 +5,13 @@
#include "JSystem/JKernel/JKRExpHeap.h"
#include "m_Do/m_Do_ext.h"
CPaneMgrAlpha::CPaneMgrAlpha() {}
#if TARGET_PC
#include "dusk/interp/user_interface.h"
#endif
CPaneMgrAlpha::CPaneMgrAlpha() {
IF_DUSK(mAlphaAnimation.active = false);
}
CPaneMgrAlpha::CPaneMgrAlpha(J2DScreen* p_screen, u64 tag, u8 flags, JKRExpHeap* p_heap) {
J2DPane* pane = p_screen->search(tag);
@@ -21,6 +27,8 @@ CPaneMgrAlpha::~CPaneMgrAlpha() {
}
void CPaneMgrAlpha::initiateAlpha(J2DPane* p_pane, JKRExpHeap* p_heap) {
IF_DUSK(mAlphaAnimation.active = false);
mPane = p_pane;
if (p_heap != NULL) {
@@ -68,7 +76,7 @@ bool CPaneMgrAlpha::isVisible() {
return mPane->isVisible();
}
f32 CPaneMgrAlpha::rateCalc(s16 maxTimer, s16 curTimer, u8 calcType) {
f32 CPaneMgrAlpha::rateCalc(DUSK_IF_ELSE(f32, s16) maxTimer, DUSK_IF_ELSE(f32, s16) curTimer, u8 calcType) {
if (maxTimer <= curTimer) {
return 1.0f;
}
@@ -105,7 +113,22 @@ f32 CPaneMgrAlpha::getAlphaRate() {
return rate;
}
#if TARGET_PC
void CPaneMgrAlpha::presentAlphaAnime() {
dusk::vdt::present_animation(mAlphaAnimation, mAlphaTimer, *this, [&](f32 rate) {
setAlpha(mAlphaAnimation.start + rate * (f32)(mAlphaAnimation.end - mAlphaAnimation.start));
});
}
#endif
bool CPaneMgrAlpha::alphaAnime(s16 timer, u8 startAlpha, u8 endAlpha, u8 calcType) {
#if TARGET_PC
if (!dusk::vdt::request_animation(mAlphaAnimation, mAlphaTimer, timer, startAlpha, endAlpha, calcType)) {
return false;
}
setAlpha(endAlpha);
return true;
#else
if (mAlphaTimer < timer - 1) {
mAlphaTimer++;
f32 rate = rateCalc(timer, mAlphaTimer, calcType);
@@ -117,20 +140,41 @@ bool CPaneMgrAlpha::alphaAnime(s16 timer, u8 startAlpha, u8 endAlpha, u8 calcTyp
}
return false;
#endif
}
bool CPaneMgrAlpha::alphaAnimeLoop(s16 param_0, u8 param_1, u8 param_2, u8 param_3) {
bool ret = false;
s16 temp_r4 = param_0 / 2;
#if TARGET_PC
mAlphaAnimation.active = false;
if (param_0 <= 0) {
mAlphaTimer = 0.0f;
setAlpha(param_1);
return true;
}
const f32 frames = dusk::game_clock::original_frames();
if (frames <= 0.0f) {
return false;
}
if (mAlphaTimer >= param_0) {
mAlphaTimer = 0.0f;
ret = true;
} else {
ret = mAlphaTimer + frames >= param_0;
dusk::vdt::advance_looping_frame(mAlphaTimer, 1.0f, param_0);
}
#else
mAlphaTimer++;
if (mAlphaTimer >= param_0) {
mAlphaTimer = 0;
ret = true;
}
#endif
s16 tmp;
DUSK_IF_ELSE(f32, s16) tmp;
if (mAlphaTimer < temp_r4) {
tmp = mAlphaTimer;
} else {
+9
View File
@@ -1,5 +1,6 @@
#pragma once
#include "JSystem/JUtility/TColor.h"
#include "SSystem/SComponent/c_angle.h"
#include "SSystem/SComponent/c_sxyz.h"
#include "SSystem/SComponent/c_xyz.h"
@@ -49,5 +50,13 @@ inline void lerp(Mtx& out, const Mtx& lhs, const Mtx& rhs, float step) {
}
}
inline JUtility::TColor lerp(const JUtility::TColor& lhs, const JUtility::TColor& rhs, float step) {
return JUtility::TColor(
lerp(lhs.r, rhs.r, step),
lerp(lhs.g, rhs.g, step),
lerp(lhs.b, rhs.b, step),
lerp(lhs.a, rhs.a, step));
}
} // namespace dusk::interp
#endif
+54
View File
@@ -0,0 +1,54 @@
#pragma once
#include "dusk/game_clock.h"
#include <dolphin/types.h>
#include <algorithm>
#include <cmath>
namespace dusk::vdt {
inline void advance_looping_frame(f32& frame, f32 speed, f32 max) {
if (max <= 0.0f) {
return;
}
frame += speed * game_clock::original_frames();
if (frame >= max) {
frame = fmodf(frame, max);
}
}
inline void advance_toward_frame(f32& frame, f32 target, f32 speed) {
if (frame == target) {
return;
}
const f32 step = speed * game_clock::original_frames();
frame = frame < target ? std::min(frame + step, target) : std::max(frame - step, target);
}
template <typename Animation>
bool request_animation(Animation& animation, f32& frame, s16 time,
decltype(animation.start) from, decltype(animation.end) to, u8 curve) {
if (frame < time) {
animation = {true, time, curve, from, to};
return false;
}
animation.active = false;
frame = time;
return true;
}
template <typename Animation, typename Pane, typename Apply>
void present_animation(Animation& animation, f32& frame, Pane& pane, Apply apply) {
if (!animation.active) {
return;
}
advance_toward_frame(frame, animation.duration, 1.0f);
apply(pane.rateCalc(animation.duration, frame, animation.curve));
if (frame >= animation.duration) {
animation.active = false;
}
}
} // namespace dusk::vdt