summaryrefslogtreecommitdiff
path: root/soh/src/code
diff options
context:
space:
mode:
authorMelonSpeedruns <melonspeedruns@outlook.com>2022-05-18 11:21:22 -0400
committerGitHub <noreply@github.com>2022-05-18 11:21:22 -0400
commit72bacabf4556ea6c3bc49fdd333d84e49e54b8b3 (patch)
tree6e77841e86d73b7cb2df2ac6ba3a138d2cecf268 /soh/src/code
parenta3a65a1722e73e88ee7c2fe377b5ab3d39d684d6 (diff)
parent076887e71f52d4258aa8fc77d3efeafe09d234d8 (diff)
Merge branch 'HarbourMasters:develop' into develop
Diffstat (limited to 'soh/src/code')
-rw-r--r--soh/src/code/graph.c5
-rw-r--r--soh/src/code/sys_matrix.c22
-rw-r--r--soh/src/code/z_actor.c8
-rw-r--r--soh/src/code/z_camera.c5
-rw-r--r--soh/src/code/z_eff_blure.c4
-rw-r--r--soh/src/code/z_eff_shield_particle.c4
-rw-r--r--soh/src/code/z_eff_spark.c4
-rw-r--r--soh/src/code/z_effect_soft_sprite.c5
-rw-r--r--soh/src/code/z_lifemeter.c4
-rw-r--r--soh/src/code/z_lights.c4
-rw-r--r--soh/src/code/z_parameter.c10
-rw-r--r--soh/src/code/z_play.c4
-rw-r--r--soh/src/code/z_player_lib.c3
-rw-r--r--soh/src/code/z_skin_matrix.c3
-rw-r--r--soh/src/code/z_view.c107
-rw-r--r--soh/src/code/z_vr_box_draw.c5
16 files changed, 177 insertions, 20 deletions
diff --git a/soh/src/code/graph.c b/soh/src/code/graph.c
index 4b1887c18..651d405d5 100644
--- a/soh/src/code/graph.c
+++ b/soh/src/code/graph.c
@@ -478,7 +478,10 @@ static void RunFrame()
Graph_StartFrame();
- PadMgr_ThreadEntry(&gPadMgr);
+ // TODO: Workaround for rumble being too long. Implement os thread functions.
+ for (int i = 0; i < 3; i++) {
+ PadMgr_ThreadEntry(&gPadMgr);
+ }
Graph_Update(&runFrameContext.gfxCtx, runFrameContext.gameState);
ticksB = GetPerfCounter();
diff --git a/soh/src/code/sys_matrix.c b/soh/src/code/sys_matrix.c
index 9d7c73967..bc90bf669 100644
--- a/soh/src/code/sys_matrix.c
+++ b/soh/src/code/sys_matrix.c
@@ -1,5 +1,7 @@
#include "global.h"
+#include "soh/frame_interpolation.h"
+
// clang-format off
Mtx gMtxClear = {
65536, 0, 1, 0,
@@ -25,11 +27,13 @@ void Matrix_Init(GameState* gameState) {
}
void Matrix_Push(void) {
+ FrameInterpolation_RecordMatrixPush();
Matrix_MtxFCopy(sCurrentMatrix + 1, sCurrentMatrix);
sCurrentMatrix++;
}
void Matrix_Pop(void) {
+ FrameInterpolation_RecordMatrixPop();
sCurrentMatrix--;
ASSERT(sCurrentMatrix >= sMatrixStack, "Matrix_now >= Matrix_stack", "../sys_matrix.c", 176);
}
@@ -39,6 +43,7 @@ void Matrix_Get(MtxF* dest) {
}
void Matrix_Put(MtxF* src) {
+ FrameInterpolation_RecordMatrixPut(src);
Matrix_MtxFCopy(sCurrentMatrix, src);
}
@@ -47,6 +52,7 @@ MtxF* Matrix_GetCurrent(void) {
}
void Matrix_Mult(MtxF* mf, u8 mode) {
+ FrameInterpolation_RecordMatrixMult(mf, mode);
MtxF* cmf = Matrix_GetCurrent();
if (mode == MTXMODE_APPLY) {
@@ -57,6 +63,7 @@ void Matrix_Mult(MtxF* mf, u8 mode) {
}
void Matrix_Translate(f32 x, f32 y, f32 z, u8 mode) {
+ FrameInterpolation_RecordMatrixTranslate(x, y, z, mode);
MtxF* cmf = sCurrentMatrix;
f32 tx;
f32 ty;
@@ -80,6 +87,7 @@ void Matrix_Translate(f32 x, f32 y, f32 z, u8 mode) {
}
void Matrix_Scale(f32 x, f32 y, f32 z, u8 mode) {
+ FrameInterpolation_RecordMatrixScale(x, y, z, mode);
MtxF* cmf = sCurrentMatrix;
if (mode == MTXMODE_APPLY) {
@@ -101,6 +109,7 @@ void Matrix_Scale(f32 x, f32 y, f32 z, u8 mode) {
}
void Matrix_RotateX(f32 x, u8 mode) {
+ FrameInterpolation_RecordMatrixRotate1Coord(0, x, mode);
MtxF* cmf;
f32 sin;
f32 cos;
@@ -165,6 +174,7 @@ void Matrix_RotateX(f32 x, u8 mode) {
}
void Matrix_RotateY(f32 y, u8 mode) {
+ FrameInterpolation_RecordMatrixRotate1Coord(1, y, mode);
MtxF* cmf;
f32 sin;
f32 cos;
@@ -229,6 +239,7 @@ void Matrix_RotateY(f32 y, u8 mode) {
}
void Matrix_RotateZ(f32 z, u8 mode) {
+ FrameInterpolation_RecordMatrixRotate1Coord(2, z, mode);
MtxF* cmf;
f32 sin;
f32 cos;
@@ -299,6 +310,7 @@ void Matrix_RotateZ(f32 z, u8 mode) {
* Original Name: Matrix_RotateXYZ, changed to reflect rotation order.
*/
void Matrix_RotateZYX(s16 x, s16 y, s16 z, u8 mode) {
+ FrameInterpolation_RecordMatrixRotateZYX(x, y, z, mode);
MtxF* cmf = sCurrentMatrix;
f32 temp1;
f32 temp2;
@@ -389,6 +401,7 @@ void Matrix_RotateZYX(s16 x, s16 y, s16 z, u8 mode) {
* transformed according to whatever the matrix was previously.
*/
void Matrix_TranslateRotateZYX(Vec3f* translation, Vec3s* rotation) {
+ FrameInterpolation_RecordMatrixTranslateRotateZYX(translation, rotation);
MtxF* cmf = sCurrentMatrix;
f32 sin = Math_SinS(rotation->z);
f32 cos = Math_CosS(rotation->z);
@@ -530,15 +543,20 @@ void Matrix_SetTranslateRotateYXZ(f32 translateX, f32 translateY, f32 translateZ
} else {
cmf->yx = 0.0f;
}
+ FrameInterpolation_RecordMatrixSetTranslateRotateYXZ(translateX, translateY, translateZ, rot);
}
Mtx* Matrix_MtxFToMtx(MtxF* src, Mtx* dest) {
+ FrameInterpolation_RecordMatrixMtxFToMtx(src, dest);
guMtxF2L(src, dest);
return dest;
}
Mtx* Matrix_ToMtx(Mtx* dest, char* file, s32 line) {
- return Matrix_MtxFToMtx(Matrix_CheckFloats(sCurrentMatrix, file, line), dest);
+ FrameInterpolation_RecordMatrixToMtx(dest, file, line);
+ guMtxF2L(Matrix_CheckFloats(sCurrentMatrix, file, line), dest);
+ return dest;
+ //return Matrix_MtxFToMtx(Matrix_CheckFloats(sCurrentMatrix, file, line), dest);
}
Mtx* Matrix_NewMtx(GraphicsContext* gfxCtx, char* file, s32 line) {
@@ -627,6 +645,7 @@ void Matrix_Transpose(MtxF* mf) {
* seen as replacing the R rotation with `mf`, hence the function name.
*/
void Matrix_ReplaceRotation(MtxF* mf) {
+ FrameInterpolation_RecordMatrixReplaceRotation(mf);
MtxF* cmf = sCurrentMatrix;
f32 acc;
f32 temp;
@@ -779,6 +798,7 @@ void Matrix_MtxFToZYXRotS(MtxF* mf, Vec3s* rotDest, s32 flag) {
* NB: `axis` is assumed to be a unit vector.
*/
void Matrix_RotateAxis(f32 angle, Vec3f* axis, u8 mode) {
+ FrameInterpolation_RecordMatrixRotateAxis(angle, axis, mode);
MtxF* cmf;
f32 sin;
f32 cos;
diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c
index a9f50f687..caa16a7ec 100644
--- a/soh/src/code/z_actor.c
+++ b/soh/src/code/z_actor.c
@@ -6,6 +6,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
#include "objects/object_bdoor/object_bdoor.h"
+#include "soh/frame_interpolation.h"
#if defined(_MSC_VER) || defined(__GNUC__)
#include <string.h>
@@ -410,6 +411,7 @@ void func_8002C124(TargetContext* targetCtx, GlobalContext* globalCtx) {
f32 var2;
s32 i;
+ FrameInterpolation_RecordOpenChild(actor, 0);
player = GET_PLAYER(globalCtx);
spCE = 0xFF;
@@ -486,10 +488,12 @@ void func_8002C124(TargetContext* targetCtx, GlobalContext* globalCtx) {
}
}
}
+ FrameInterpolation_RecordCloseChild();
}
actor = targetCtx->unk_94;
if ((actor != NULL) && !(actor->flags & ACTOR_FLAG_27)) {
+ FrameInterpolation_RecordOpenChild(actor, 1);
NaviColor* naviColor = &sNaviColorList[actor->category];
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x7);
@@ -503,6 +507,7 @@ void func_8002C124(TargetContext* targetCtx, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 2153),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, gZTargetArrowDL);
+ FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 2158);
@@ -2490,6 +2495,7 @@ void Actor_Draw(GlobalContext* globalCtx, Actor* actor) {
Fault_AddClient(&faultClient, Actor_FaultPrint, actor, "Actor_draw");
+ FrameInterpolation_RecordOpenChild(actor, 0);
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 6035);
lights = LightContext_NewLights(&globalCtx->lightCtx, globalCtx->state.gfxCtx);
@@ -2497,6 +2503,7 @@ void Actor_Draw(GlobalContext* globalCtx, Actor* actor) {
Lights_BindAll(lights, globalCtx->lightCtx.listHead, (actor->flags & ACTOR_FLAG_22) ? NULL : &actor->world.pos);
Lights_Draw(lights, globalCtx->state.gfxCtx);
+ FrameInterpolation_RecordActorPosRotMatrix();
if (actor->flags & ACTOR_FLAG_12) {
Matrix_SetTranslateRotateYXZ(
actor->world.pos.x + globalCtx->mainCamera.skyboxOffset.x,
@@ -2546,6 +2553,7 @@ void Actor_Draw(GlobalContext* globalCtx, Actor* actor) {
}
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 6119);
+ FrameInterpolation_RecordCloseChild();
Fault_RemoveClient(&faultClient);
}
diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c
index 41c16b5cc..00f3f70f0 100644
--- a/soh/src/code/z_camera.c
+++ b/soh/src/code/z_camera.c
@@ -6,6 +6,8 @@
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
+#include "soh/frame_interpolation.h"
+
s16 Camera_ChangeSettingFlags(Camera* camera, s16 setting, s16 flags);
s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags);
s32 Camera_QRegInit(void);
@@ -6675,6 +6677,7 @@ s32 Camera_Special9(Camera* camera) {
case 1:
spec9->doorParams.timer1--;
if (spec9->doorParams.timer1 <= 0) {
+ FrameInterpolation_DontInterpolateCamera();
camera->animState++;
if (params->interfaceFlags & 1) {
camPosData = Camera_GetCamBGData(camera);
@@ -7968,6 +7971,8 @@ s32 Camera_SetCSParams(Camera* camera, CutsceneCameraPoint* atPoints, CutsceneCa
camera->speedRatio = 0.0f;
}
+ FrameInterpolation_DontInterpolateCamera();
+
return 1;
}
diff --git a/soh/src/code/z_eff_blure.c b/soh/src/code/z_eff_blure.c
index e08f8f337..f3a1e6122 100644
--- a/soh/src/code/z_eff_blure.c
+++ b/soh/src/code/z_eff_blure.c
@@ -1,6 +1,8 @@
#include "global.h"
#include "objects/gameplay_keep/gameplay_keep.h"
+#include "soh/frame_interpolation.h"
+
void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2) {
EffectBlureElement* elem;
s32 numElements;
@@ -946,6 +948,7 @@ void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) {
s32 j;
s32 phi_t2;
+ FrameInterpolation_RecordOpenChild(this, 0);
OPEN_DISPS(gfxCtx, "../z_eff_blure.c", 1596);
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
@@ -1059,4 +1062,5 @@ void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) {
}
CLOSE_DISPS(gfxCtx, "../z_eff_blure.c", 1823);
+ FrameInterpolation_RecordCloseChild();
}
diff --git a/soh/src/code/z_eff_shield_particle.c b/soh/src/code/z_eff_shield_particle.c
index fad499286..73134a654 100644
--- a/soh/src/code/z_eff_shield_particle.c
+++ b/soh/src/code/z_eff_shield_particle.c
@@ -2,6 +2,8 @@
#include "vt.h"
#include "objects/gameplay_keep/gameplay_keep.h"
+#include "soh/frame_interpolation.h"
+
static Vtx sVertices[5] = {
VTX(-32, -32, 0, 0, 1024, 0xFF, 0xFF, 0xFF, 0xFF),
VTX(32, 32, 0, 1024, 0, 0xFF, 0xFF, 0xFF, 0xFF),
@@ -154,6 +156,7 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
Color_RGBA8 primColor;
Color_RGBA8 envColor;
+ FrameInterpolation_RecordOpenChild(this, 0);
OPEN_DISPS(gfxCtx, "../z_eff_shield_particle.c", 272);
if (this != NULL) {
@@ -213,4 +216,5 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
}
CLOSE_DISPS(gfxCtx, "../z_eff_shield_particle.c", 359);
+ FrameInterpolation_RecordCloseChild();
}
diff --git a/soh/src/code/z_eff_spark.c b/soh/src/code/z_eff_spark.c
index cfe8f628f..b76968371 100644
--- a/soh/src/code/z_eff_spark.c
+++ b/soh/src/code/z_eff_spark.c
@@ -1,6 +1,8 @@
#include "global.h"
#include "objects/gameplay_keep/gameplay_keep.h"
+#include "soh/frame_interpolation.h"
+
// original name: "spark"
void EffectSpark_Init(void* thisx, void* initParamsx) {
EffectSpark* this = (EffectSpark*)thisx;
@@ -152,6 +154,7 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
u8 sp1C4;
f32 ratio;
+ FrameInterpolation_RecordOpenChild(this, 0);
OPEN_DISPS(gfxCtx, "../z_eff_spark.c", 293);
if (this != NULL) {
@@ -274,4 +277,5 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
end:
CLOSE_DISPS(gfxCtx, "../z_eff_spark.c", 498);
+ FrameInterpolation_RecordCloseChild();
}
diff --git a/soh/src/code/z_effect_soft_sprite.c b/soh/src/code/z_effect_soft_sprite.c
index aa0b922fe..2548966cc 100644
--- a/soh/src/code/z_effect_soft_sprite.c
+++ b/soh/src/code/z_effect_soft_sprite.c
@@ -1,6 +1,8 @@
#include "global.h"
#include "vt.h"
+#include "soh/frame_interpolation.h"
+
EffectSsInfo sEffectSsInfo = { 0 }; // "EffectSS2Info"
void EffectSs_InitInfo(GlobalContext* globalCtx, s32 tableSize) {
@@ -233,6 +235,7 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init
sEffectSsInfo.table[index].type = type;
sEffectSsInfo.table[index].priority = priority;
+ sEffectSsInfo.table[index].epoch++;
if (initInfo->init(globalCtx, index, &sEffectSsInfo.table[index], initParams) == 0) {
osSyncPrintf(VT_FGCOL(GREEN));
@@ -284,7 +287,9 @@ void EffectSs_Draw(GlobalContext* globalCtx, s32 index) {
EffectSs* effectSs = &sEffectSsInfo.table[index];
if (effectSs->draw != NULL) {
+ FrameInterpolation_RecordOpenChild(effectSs, effectSs->epoch);
effectSs->draw(globalCtx, index, effectSs);
+ FrameInterpolation_RecordCloseChild();
}
}
diff --git a/soh/src/code/z_lifemeter.c b/soh/src/code/z_lifemeter.c
index 344022505..5f1863440 100644
--- a/soh/src/code/z_lifemeter.c
+++ b/soh/src/code/z_lifemeter.c
@@ -498,8 +498,8 @@ void HealthMeter_HandleCriticalAlarm(GlobalContext* globalCtx) {
if (interfaceCtx->unk_22A <= 0) {
interfaceCtx->unk_22A = 0;
interfaceCtx->unk_22C = 0;
- if (!Player_InCsMode(globalCtx) && (globalCtx->pauseCtx.state == 0) &&
- (globalCtx->pauseCtx.debugState == 0) && HealthMeter_IsCritical() && !Gameplay_InCsMode(globalCtx)) {
+ if (CVar_GetS32("gLowHpAlarm", 0) == 0 && !Player_InCsMode(globalCtx) && (globalCtx->pauseCtx.state == 0) &&
+ (globalCtx->pauseCtx.debugState == 0) && HealthMeter_IsCritical() && !Gameplay_InCsMode(globalCtx)) {
func_80078884(NA_SE_SY_HITPOINT_ALARM);
}
}
diff --git a/soh/src/code/z_lights.c b/soh/src/code/z_lights.c
index c9b60ceca..bee677276 100644
--- a/soh/src/code/z_lights.c
+++ b/soh/src/code/z_lights.c
@@ -4,6 +4,8 @@
#include "objects/gameplay_keep/gameplay_keep.h"
+#include "soh/frame_interpolation.h"
+
#define LIGHTS_BUFFER_SIZE 32
//#define LIGHTS_BUFFER_SIZE 1024 // Kill me
@@ -434,12 +436,14 @@ void Lights_DrawGlow(GlobalContext* globalCtx) {
if ((info->type == LIGHT_POINT_GLOW) && (params->drawGlow)) {
scale = SQ(params->radius) * 0.0000026f;
+ FrameInterpolation_RecordOpenChild(node, 0);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, params->color[0], params->color[1], params->color[2], 50);
Matrix_Translate(params->x, params->y, params->z, MTXMODE_NEW);
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_lights.c", 918),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gGlowCircleDL);
+ FrameInterpolation_RecordCloseChild();
}
node = node->next;
diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c
index edc4348b9..8cfcccbf5 100644
--- a/soh/src/code/z_parameter.c
+++ b/soh/src/code/z_parameter.c
@@ -753,7 +753,15 @@ void func_80083108(GlobalContext* globalCtx) {
gSaveContext.buttonStatus[0] = BTN_DISABLED;
for (i = 1; i < 4; i++) {
- if (func_8008F2F8(globalCtx) == 2) {
+ if ((gSaveContext.equips.buttonItems[i] >= ITEM_SHIELD_DEKU) &&
+ (gSaveContext.equips.buttonItems[i] <= ITEM_BOOTS_HOVER)) {
+ // Equipment on c-buttons is always enabled
+ if (gSaveContext.buttonStatus[i] == BTN_DISABLED) {
+ sp28 = 1;
+ }
+
+ gSaveContext.buttonStatus[i] = BTN_ENABLED;
+ } else if (func_8008F2F8(globalCtx) == 2) {
if ((gSaveContext.equips.buttonItems[i] != ITEM_HOOKSHOT) &&
(gSaveContext.equips.buttonItems[i] != ITEM_LONGSHOT)) {
if (gSaveContext.buttonStatus[i] == BTN_ENABLED) {
diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c
index 2934e5e1b..632ed41f6 100644
--- a/soh/src/code/z_play.c
+++ b/soh/src/code/z_play.c
@@ -5,6 +5,8 @@
#include "soh/Enhancements/gameconsole.h"
+#include "soh/frame_interpolation.h"
+
void* D_8012D1F0 = NULL;
//UNK_TYPE D_8012D1F4 = 0; // unused
Input* D_8012D1F8 = NULL;
@@ -1379,7 +1381,9 @@ void Gameplay_Main(GameState* thisx) {
LOG_NUM("1", 1, "../z_play.c", 4583);
}
+ FrameInterpolation_StartRecord();
Gameplay_Draw(globalCtx);
+ FrameInterpolation_StopRecord();
if (1 && HREG(63)) {
LOG_NUM("1", 1, "../z_play.c", 4587);
diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c
index 355d323e0..4e4e1ff70 100644
--- a/soh/src/code/z_player_lib.c
+++ b/soh/src/code/z_player_lib.c
@@ -29,7 +29,8 @@ s16 sBootData[PLAYER_BOOTS_MAX][17] = {
// Used to map action params to model groups
u8 sActionModelGroups[] = {
3, 15, 10, 2, 2, 5, 10, 11, 6, 6, 6, 6, 6, 6, 6, 6, 9, 9, 7, 7, 8, 3, 3, 6, 3, 3, 3, 3, 12, 13, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3
};
TextTriggerEntry sTextTriggers[] = {
diff --git a/soh/src/code/z_skin_matrix.c b/soh/src/code/z_skin_matrix.c
index f7df8091f..d822d6c13 100644
--- a/soh/src/code/z_skin_matrix.c
+++ b/soh/src/code/z_skin_matrix.c
@@ -1,6 +1,8 @@
#include "global.h"
#include "vt.h"
+#include "soh/frame_interpolation.h"
+
// clang-format off
MtxF sMtxFClear = {
1.0f, 0.0f, 0.0f, 0.0f,
@@ -523,6 +525,7 @@ void SkinMatrix_Vec3sToVec3f(Vec3s* src, Vec3f* dest) {
}
void SkinMatrix_MtxFToMtx(MtxF* src, Mtx* dest) {
+ FrameInterpolation_RecordSkinMatrixMtxFToMtx(src, dest);
guMtxF2L(src, dest);
}
diff --git a/soh/src/code/z_view.c b/soh/src/code/z_view.c
index 97f1ad26e..e03daee83 100644
--- a/soh/src/code/z_view.c
+++ b/soh/src/code/z_view.c
@@ -2,6 +2,9 @@
#include "vt.h"
#include <string.h>
+#include <math.h>
+
+#include "soh/frame_interpolation.h"
vu32 D_8012ABF0 = true;
@@ -277,6 +280,10 @@ void func_800AAA50(View* view, s32 arg1) {
}
}
+static float sqr(float a) {
+ return a * a;
+}
+
s32 func_800AAA9C(View* view) {
f32 aspect;
s32 width;
@@ -307,6 +314,85 @@ s32 func_800AAA9C(View* view) {
height = view->viewport.bottomY - view->viewport.topY;
aspect = (f32)width / (f32)height;
+ viewing = Graph_Alloc(gfxCtx, sizeof(Mtx));
+ LogUtils_CheckNullPointer("viewing", viewing, "../z_view.c", 667);
+ view->viewingPtr = viewing;
+
+ if (view->eye.x == view->lookAt.x && view->eye.y == view->lookAt.y && view->eye.z == view->lookAt.z) {
+ view->eye.x += 1.0f;
+ view->eye.y += 1.0f;
+ view->eye.z += 1.0f;
+ }
+
+ func_800ABE74(view->eye.x, view->eye.y, view->eye.z);
+ MtxF viewingF;
+ guLookAtF(viewingF.mf, view->eye.x, view->eye.y, view->eye.z, view->lookAt.x, view->lookAt.y, view->lookAt.z, view->up.x,
+ view->up.y, view->up.z);
+
+ // Some heuristics to identify instant camera movements and skip interpolation in that case
+
+ static View old_view;
+
+ float dirx = view->eye.x - view->lookAt.x;
+ float diry = view->eye.y - view->lookAt.y;
+ float dirz = view->eye.z - view->lookAt.z;
+ float dir_dist = sqrtf(sqr(dirx) + sqr(diry) + sqr(dirz));
+ dirx /= dir_dist;
+ diry /= dir_dist;
+ dirz /= dir_dist;
+
+ float odirx = old_view.eye.x - old_view.lookAt.x;
+ float odiry = old_view.eye.y - old_view.lookAt.y;
+ float odirz = old_view.eye.z - old_view.lookAt.z;
+ float odir_dist = sqrtf(sqr(odirx) + sqr(odiry) + sqr(odirz));
+ odirx /= odir_dist;
+ odiry /= odir_dist;
+ odirz /= odir_dist;
+
+ float eye_dist = sqrtf(sqr(view->eye.x - old_view.eye.x) + sqr(view->eye.y - old_view.eye.y) + sqr(view->eye.z - old_view.eye.z));
+ float look_dist = sqrtf(sqr(view->lookAt.x - old_view.lookAt.x) + sqr(view->lookAt.y - old_view.lookAt.y) + sqr(view->lookAt.z - old_view.lookAt.z));
+ float up_dist = sqrtf(sqr(view->up.x - old_view.up.x) + sqr(view->up.y - old_view.up.y) + sqr(view->up.z - old_view.up.z));
+ float d_dist = sqrtf(sqr(dirx - odirx) + sqr(diry - odiry) + sqr(dirz - odirz));
+
+ bool dont_interpolate = false;
+
+ if (up_dist < 0.01 && d_dist < 0.01) {
+ if (eye_dist + look_dist > 300) {
+ dont_interpolate = true;
+ }
+ } else {
+ if (eye_dist >= 400) {
+ dont_interpolate = true;
+ }
+ if (look_dist >= 100) {
+ dont_interpolate = true;
+ }
+ if (up_dist >= 1.50f) {
+ dont_interpolate = true;
+ }
+ if (d_dist >= 1.414f && look_dist >= 15) {
+ dont_interpolate = true;
+ }
+ if (d_dist >= 1.414f && up_dist >= 0.31f && look_dist >= 1 && eye_dist >= 300) {
+ dont_interpolate = true;
+ }
+ if (d_dist >= 0.5f && up_dist >= 0.31f && look_dist >= 3 && eye_dist >= 170) {
+ dont_interpolate = true;
+ }
+ if (look_dist >= 52 && eye_dist >= 52) {
+ dont_interpolate = true;
+ }
+ if (look_dist >= 30 && eye_dist >= 90) {
+ dont_interpolate = true;
+ }
+ }
+
+ if (dont_interpolate) {
+ FrameInterpolation_DontInterpolateCamera();
+ }
+
+ FrameInterpolation_RecordOpenChild(NULL, FrameInterpolation_GetCameraEpoch());
+
if (HREG(80) == 11) {
if (HREG(94) != 11) {
HREG(94) = 11;
@@ -347,21 +433,16 @@ s32 func_800AAA9C(View* view) {
gSPPerspNormalize(POLY_KAL_DISP++, view->normal);
gSPMatrix(POLY_KAL_DISP++, projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
- viewing = Graph_Alloc(gfxCtx, sizeof(Mtx));
- LogUtils_CheckNullPointer("viewing", viewing, "../z_view.c", 667);
- view->viewingPtr = viewing;
+ Matrix_MtxFToMtx(viewingF.mf, viewing);
- if (view->eye.x == view->lookAt.x && view->eye.y == view->lookAt.y && view->eye.z == view->lookAt.z) {
- view->eye.x += 1.0f;
- view->eye.y += 1.0f;
- view->eye.z += 1.0f;
- }
+ view->viewing = *viewing;
- func_800ABE74(view->eye.x, view->eye.y, view->eye.z);
- guLookAt(viewing, view->eye.x, view->eye.y, view->eye.z, view->lookAt.x, view->lookAt.y, view->lookAt.z, view->up.x,
- view->up.y, view->up.z);
- view->viewing = *viewing;
+ /*if (eye_dist > 1 || look_dist > 1 || abs(up_dist) > 0.1 || abs(d_dist) > 0.1)
+ printf("%d %f %f %f, %f %f %f, %f %f %f, %f %f %f %f %d\n", (int)view->fovy, view->eye.x, view->eye.y, view->eye.z, view->lookAt.x, view->lookAt.y, view->lookAt.z,
+ view->up.x, view->up.y, view->up.z, eye_dist, look_dist, up_dist, d_dist, dont_interpolate);*/
+
+ old_view = *view;
if (QREG(88) & 2) {
s32 i;
@@ -374,10 +455,10 @@ s32 func_800AAA9C(View* view) {
}
osSyncPrintf("\n");
}
-
gSPMatrix(POLY_OPA_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
gSPMatrix(POLY_XLU_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
gSPMatrix(POLY_KAL_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
+ FrameInterpolation_RecordCloseChild();
CLOSE_DISPS(gfxCtx, "../z_view.c", 711);
diff --git a/soh/src/code/z_vr_box_draw.c b/soh/src/code/z_vr_box_draw.c
index 292789333..13eb93bd0 100644
--- a/soh/src/code/z_vr_box_draw.c
+++ b/soh/src/code/z_vr_box_draw.c
@@ -1,5 +1,7 @@
#include "global.h"
+#include "soh/frame_interpolation.h"
+
Mtx* sSkyboxDrawMatrix;
Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z) {
@@ -13,6 +15,7 @@ Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z) {
void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z) {
OPEN_DISPS(gfxCtx, "../z_vr_box_draw.c", 52);
+ FrameInterpolation_RecordOpenChild(NULL, FrameInterpolation_GetCameraEpoch());
func_800945A0(gfxCtx);
@@ -85,7 +88,7 @@ void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyb
gDPPipeSync(POLY_OPA_DISP++);
//gsSPShaderTest2(POLY_OPA_DISP++);
-
+ FrameInterpolation_RecordCloseChild();
CLOSE_DISPS(gfxCtx, "../z_vr_box_draw.c", 125);
}