Added patches for skipping interpolation when actors get teleported in cutscenes

This commit is contained in:
Mr-Wiseguy 2024-04-06 00:34:10 -04:00
parent bd537728e3
commit 460d1aafb4
9 changed files with 432 additions and 6 deletions

View File

@ -6,6 +6,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
# set(CMAKE_CXX_VISIBILITY_PRESET hidden) # set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-everything -Wall -Wextra")
# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24: # Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24:
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
cmake_policy(SET CMP0135 NEW) cmake_policy(SET CMP0135 NEW)

View File

@ -1164,6 +1164,7 @@ void tag_actor_displaylists(Actor* actor, PlayState* play, Gfx* opa_start, Gfx*
// Scan the commands written by the actor to see how many matrices were added. // Scan the commands written by the actor to see how many matrices were added.
s32 opa_matrices = scan_for_matrices(opa_start, POLY_OPA_DISP); s32 opa_matrices = scan_for_matrices(opa_start, POLY_OPA_DISP);
s32 xlu_matrices = scan_for_matrices(xlu_start, POLY_XLU_DISP); s32 xlu_matrices = scan_for_matrices(xlu_start, POLY_XLU_DISP);
bool skipped = actor_get_interpolation_skipped(actor);
// If the actor wrote at least one matrix in total and at most one matrix to each list, tag that matrix with the actor's id. // If the actor wrote at least one matrix in total and at most one matrix to each list, tag that matrix with the actor's id.
if ((opa_matrices == 1 || xlu_matrices == 1) && opa_matrices <= 1 && xlu_matrices <= 1) { if ((opa_matrices == 1 || xlu_matrices == 1) && opa_matrices <= 1 && xlu_matrices <= 1) {
@ -1171,7 +1172,12 @@ void tag_actor_displaylists(Actor* actor, PlayState* play, Gfx* opa_start, Gfx*
if (opa_matrices == 1) { if (opa_matrices == 1) {
// Fill in the slot that was reserved for a transform id. // Fill in the slot that was reserved for a transform id.
gEXMatrixGroupDecomposedNormal(opa_start, cur_transform_id, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW); if (skipped) {
gEXMatrixGroupDecomposedSkipPosRot(opa_start, cur_transform_id, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
else {
gEXMatrixGroupDecomposedNormal(opa_start, cur_transform_id, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
// Pop the matrix group. // Pop the matrix group.
gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW); gEXPopMatrixGroup(POLY_OPA_DISP++, G_MTX_MODELVIEW);
@ -1179,7 +1185,12 @@ void tag_actor_displaylists(Actor* actor, PlayState* play, Gfx* opa_start, Gfx*
if (xlu_matrices == 1) { if (xlu_matrices == 1) {
// Fill in the slot that was reserved for a transform id. // Fill in the slot that was reserved for a transform id.
gEXMatrixGroupDecomposedNormal(xlu_start, cur_transform_id + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW); if (skipped) {
gEXMatrixGroupDecomposedSkipPosRot(xlu_start, cur_transform_id + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
else {
gEXMatrixGroupDecomposedNormal(xlu_start, cur_transform_id + 1, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_ALLOW);
}
// Pop the matrix groups. // Pop the matrix groups.
gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW); gEXPopMatrixGroup(POLY_XLU_DISP++, G_MTX_MODELVIEW);

137
patches/cutscene_patches.c Normal file
View File

@ -0,0 +1,137 @@
#include "patches.h"
#include "transform_ids.h"
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
#define CUE_DIST_THRESHOLD 10.0f
CsCmdActorCue* prev_cues_checked[ARRAY_COUNT(((CutsceneContext*)0)->actorCues)] = {0};
void Cutscene_ActorTranslate(Actor* actor, PlayState* play, s32 cueChannel) {
Vec3f startPos;
Vec3f endPos;
CsCmdActorCue* cue = play->csCtx.actorCues[cueChannel];
f32 lerp;
startPos.x = cue->startPos.x;
startPos.y = cue->startPos.y;
startPos.z = cue->startPos.z;
endPos.x = cue->endPos.x;
endPos.y = cue->endPos.y;
endPos.z = cue->endPos.z;
lerp = Environment_LerpWeight(cue->endFrame, cue->startFrame, play->csCtx.curFrame);
// @recomp Check if this is a new cue for a given channel.
if (prev_cues_checked[cueChannel] != cue) {
// New cue, so check if the start position of this cue is significantly different than the actor's current position.
if (Math3D_Distance(&startPos, &actor->world.pos) > CUE_DIST_THRESHOLD) {
// The actor is probably being teleported, so skip interpolation for them this frame.
actor_set_interpolation_skipped(actor);
}
}
// @recomp Update tracking for this channel's most recent cue.
prev_cues_checked[cueChannel] = cue;
VEC3F_LERPIMPDST(&actor->world.pos, &startPos, &endPos, lerp);
}
extern EnHorseCsFunc D_808890F0[];
extern EnHorseCsFunc D_8088911C[];
// @recomp Patched to skip interpolation on Epona when she's teleported by a cutscene.
void func_80884718(EnHorse* this, PlayState* play) {
CsCmdActorCue* cue;
if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_112)) {
this->cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_112);
cue = play->csCtx.actorCues[this->cueChannel];
this->unk_1EC |= 0x20;
if (this->cueId != cue->id) {
if (this->cueId == -1) {
// @recomp Being teleported by a new cue, so skip interpolation.
actor_set_interpolation_skipped(&this->actor);
this->actor.world.pos.x = cue->startPos.x;
this->actor.world.pos.y = cue->startPos.y;
this->actor.world.pos.z = cue->startPos.z;
this->actor.world.rot.y = cue->rot.y;
this->actor.shape.rot = this->actor.world.rot;
this->actor.prevPos = this->actor.world.pos;
}
this->cueId = cue->id;
// @recomp Manual relocation, TODO remove when automated.
EnHorseCsFunc* D_808890F0_reloc = actor_relocate(&this->actor, D_808890F0);
if (D_808890F0_reloc[this->cueId] != NULL) {
D_808890F0_reloc[this->cueId](this, play, cue);
}
}
// @recomp Manual relocation, TODO remove when automated.
EnHorseCsFunc* D_8088911C_reloc = actor_relocate(&this->actor, D_8088911C);
if (D_8088911C_reloc[this->cueId] != NULL) {
D_8088911C_reloc[this->cueId](this, play, cue);
}
}
}
// @recomp Patched to skip interpolation on Epona when she's teleported by a cutscene.
void func_80883B70(EnHorse* this, CsCmdActorCue* cue) {
// @recomp Being teleported by a new cue, so skip interpolation.
actor_set_interpolation_skipped(&this->actor);
this->actor.world.pos.x = cue->startPos.x;
this->actor.world.pos.y = cue->startPos.y;
this->actor.world.pos.z = cue->startPos.z;
this->actor.world.rot.y = cue->rot.y;
this->actor.shape.rot = this->actor.world.rot;
this->actor.prevPos = this->actor.world.pos;
}
// @recomp Patched to skip interpolation on Link when he's teleported to a new cue.
void Player_Cutscene_SetPosAndYawToStart(Player* this, CsCmdActorCue* cue) {
// @recomp Being teleported by a new cue, so skip interpolation.
actor_set_interpolation_skipped(&this->actor);
this->actor.world.pos.x = cue->startPos.x;
this->actor.world.pos.y = cue->startPos.y;
this->actor.world.pos.z = cue->startPos.z;
this->currentYaw = this->actor.shape.rot.y = cue->rot.y;
}
CsCmdActorCue* prev_link_cue = NULL;
// @recomp Patched to skip interpolation on Link when he's teleported to a new cue.
void Player_Cutscene_Translate(PlayState* play, Player* this, CsCmdActorCue* cue) {
f32 startX = cue->startPos.x;
f32 startY = cue->startPos.y;
f32 startZ = cue->startPos.z;
f32 diffX = cue->endPos.x - startX;
f32 diffY = cue->endPos.y - startY;
f32 diffZ = cue->endPos.z - startZ;
f32 progress = (((f32)(play->csCtx.curFrame - cue->startFrame)) / ((f32)(cue->endFrame - cue->startFrame)));
// @recomp Check if this is a new cue for a given channel.
if (prev_link_cue != cue) {
// New cue, so check if the start position of this cue is significantly different than the actor's current position.
Vec3f start_pos;
start_pos.x = startX;
start_pos.y = startY;
start_pos.z = startZ;
if (Math3D_Distance(&start_pos, &this->actor.world.pos) > CUE_DIST_THRESHOLD) {
// The actor is probably being teleported, so skip interpolation for them this frame.
actor_set_interpolation_skipped(&this->actor);
}
}
prev_link_cue = cue;
this->actor.world.pos.x = (diffX * progress) + startX;
this->actor.world.pos.y = (diffY * progress) + startY;
this->actor.world.pos.z = (diffZ * progress) + startZ;
}

View File

@ -0,0 +1,221 @@
// Required to include MM decomp headers without having built the repo
#ifndef OBJECT_HA_H
#define OBJECT_HA_H 1
typedef enum DonkeyBanditLimb {
/* 0x00 */ HORSE_BANDIT_LIMB_NONE,
/* 0x01 */ HORSE_BANDIT_LIMB_ROOT,
/* 0x02 */ HORSE_BANDIT_LIMB_PELVIS,
/* 0x03 */ HORSE_BANDIT_LIMB_TORSO,
/* 0x04 */ HORSE_BANDIT_LIMB_LEFT_FRONT_LEG_ROOT,
/* 0x05 */ HORSE_BANDIT_LIMB_LEFT_FRONT_FOREARM,
/* 0x06 */ HORSE_BANDIT_LIMB_LEFT_FRONT_CANNON,
/* 0x07 */ HORSE_BANDIT_LIMB_LEFT_FRONT_FOOT,
/* 0x08 */ HORSE_BANDIT_LIMB_LOWER_NECK,
/* 0x09 */ HORSE_BANDIT_LIMB_UPPER_NECK,
/* 0x0A */ HORSE_BANDIT_LIMB_HEAD,
/* 0x0B */ HORSE_BANDIT_LIMB_RIGHT_FRONT_LEG_ROOT,
/* 0x0C */ HORSE_BANDIT_LIMB_RIGHT_FRONT_FOREARM,
/* 0x0D */ HORSE_BANDIT_LIMB_RIGHT_FRONT_CANNON,
/* 0x0E */ HORSE_BANDIT_LIMB_RIGHT_FRONT_FOOT,
/* 0x0F */ HORSE_BANDIT_LIMB_TAIL_DOCK,
/* 0x10 */ HORSE_BANDIT_LIMB_TAIL_MIDDLE,
/* 0x11 */ HORSE_BANDIT_LIMB_TAIL_END,
/* 0x12 */ HORSE_BANDIT_LIMB_LEFT_HIND_THIGH,
/* 0x13 */ HORSE_BANDIT_LIMB_LEFT_HIND_STIFLE,
/* 0x14 */ HORSE_BANDIT_LIMB_LEFT_HIND_CANNON,
/* 0x15 */ HORSE_BANDIT_LIMB_LEFT_HIND_FOOT,
/* 0x16 */ HORSE_BANDIT_LIMB_RIGHT_HIND_THIGH,
/* 0x17 */ HORSE_BANDIT_LIMB_RIGHT_HIND_STIFLE,
/* 0x18 */ HORSE_BANDIT_LIMB_RIGHT_HIND_CANNON,
/* 0x19 */ HORSE_BANDIT_LIMB_RIGHT_HIND_FOOT,
/* 0x1A */ HORSE_BANDIT_LIMB_MAX
} DonkeyBanditLimb;
typedef enum DonkeyLimb {
/* 0x00 */ DONKEY_LIMB_NONE,
/* 0x01 */ DONKEY_LIMB_ROOT,
/* 0x02 */ DONKEY_LIMB_PELVIS,
/* 0x03 */ DONKEY_LIMB_TORSO,
/* 0x04 */ DONKEY_LIMB_LEFT_FRONT_LEG_ROOT,
/* 0x05 */ DONKEY_LIMB_LEFT_FRONT_FOREARM,
/* 0x06 */ DONKEY_LIMB_LEFT_FRONT_CANNON,
/* 0x07 */ DONKEY_LIMB_LEFT_FRONT_FOOT,
/* 0x08 */ DONKEY_LIMB_LOWER_NECK,
/* 0x09 */ DONKEY_LIMB_UPPER_NECK,
/* 0x0A */ DONKEY_LIMB_HEAD,
/* 0x0B */ DONKEY_LIMB_RIGHT_FRONT_LEG_ROOT,
/* 0x0C */ DONKEY_LIMB_RIGHT_FRONT_FOREARM,
/* 0x0D */ DONKEY_LIMB_RIGHT_FRONT_CANNON,
/* 0x0E */ DONKEY_LIMB_RIGHT_FRONT_FOOT,
/* 0x0F */ DONKEY_LIMB_TAIL_DOCK,
/* 0x10 */ DONKEY_LIMB_TAIL_MIDDLE,
/* 0x11 */ DONKEY_LIMB_TAIL_END,
/* 0x12 */ DONKEY_LIMB_LEFT_HIND_THIGH,
/* 0x13 */ DONKEY_LIMB_LEFT_HIND_STIFLE,
/* 0x14 */ DONKEY_LIMB_LEFT_HIND_CANNON,
/* 0x15 */ DONKEY_LIMB_LEFT_HIND_FOOT,
/* 0x16 */ DONKEY_LIMB_RIGHT_HIND_THIGH,
/* 0x17 */ DONKEY_LIMB_RIGHT_HIND_STIFLE,
/* 0x18 */ DONKEY_LIMB_RIGHT_HIND_CANNON,
/* 0x19 */ DONKEY_LIMB_RIGHT_HIND_FOOT,
/* 0x1A */ DONKEY_LIMB_MAX
} DonkeyLimb;
extern s16 sHorseUnusedAnimFrameData[];
extern JointIndex sHorseUnusedAnimJointIndices[];
extern AnimationHeader gHorseUnusedAnim;
extern Vtx object_haVtx_0000E0[];
extern Gfx gHorseBanditRightHindFootDL[];
extern Gfx gHorseBanditRightHindCannonDL[];
extern Gfx gHorseBanditRightHindStifleDL[];
extern Gfx gHorseBanditRightHindThighDL[];
extern Gfx gHorseBanditLeftHindFootDL[];
extern Gfx gHorseBanditLeftHindCannonDL[];
extern Gfx gHorseBanditLeftHindStifleDL[];
extern Gfx gHorseBanditLeftHindThighDL[];
extern Gfx gHorseBanditTailEndDL[];
extern Gfx gHorseBanditTailMiddleDL[];
extern Gfx gHorseBanditTailDockDL[];
extern Gfx gHorseBanditPelvisDL[];
extern Gfx gHorseBanditRightFrontFootDL[];
extern Gfx gHorseBanditRightFrontCannonDL[];
extern Gfx gHorseBanditRightFrontForearmDL[];
extern Gfx gHorseBanditRightFrontLegRootDL[];
extern Gfx gHorseBanditHeadDL[];
extern Gfx gHorseBanditUpperNeckDL[];
extern Gfx gHorseBanditLowerNeckDL[];
extern Gfx gHorseBanditLeftFrontFootDL[];
extern Gfx gHorseBanditLeftFrontCannonDL[];
extern Gfx gHorseBanditLeftFrontForearmDL[];
extern Gfx gHorseBanditLeftFrontLegRootDL[];
extern Gfx gHorseBanditTorsoDL[];
extern u64 gHorseBanditTLUT[];
extern u64 gHorseBanditMaskTex[];
extern u64 gHorseBanditSpottedDetailTex[];
extern u64 gHorseBanditEyebrowTex[];
extern u64 gHorseBanditTeethTex[];
extern u64 gHorseBanditTailAndFeetTex[];
extern u64 gHorseBanditEyeTex[];
extern u64 gHorseBanditMouthTex[];
extern u64 gHorseBanditSpottedSkinTex[];
extern u64 gHorseBanditTasselTex[];
extern u64 gHorseBanditSaddleSideTex[];
extern u64 gHorseBanditSaddleTopTex[];
extern u64 gHorseBanditSaddleBackTex[];
extern StandardLimb gHorseBanditRootLimb;
extern StandardLimb gHorseBanditPelvisLimb;
extern StandardLimb gHorseBanditTorsoLimb;
extern StandardLimb gHorseBanditLeftFrontLegRootLimb;
extern StandardLimb gHorseBanditLeftFrontForearmLimb;
extern StandardLimb gHorseBanditLeftFrontCannonLimb;
extern StandardLimb gHorseBanditLeftFrontFootLimb;
extern StandardLimb gHorseBanditLowerNeckLimb;
extern StandardLimb gHorseBanditUpperNeckLimb;
extern StandardLimb gHorseBanditHeadLimb;
extern StandardLimb gHorseBanditRightFrontLegRootLimb;
extern StandardLimb gHorseBanditRightFrontForearmLimb;
extern StandardLimb gHorseBanditRightFrontCannonLimb;
extern StandardLimb gHorseBanditRightFrontFootLimb;
extern StandardLimb gHorseBanditTailDockLimb;
extern StandardLimb gHorseBanditTailMiddleLimb;
extern StandardLimb gHorseBanditTailEndLimb;
extern StandardLimb gHorseBanditLeftHindThighLimb;
extern StandardLimb gHorseBanditLeftHindStifleLimb;
extern StandardLimb gHorseBanditLeftHindCannonLimb;
extern StandardLimb gHorseBanditLeftHindFootLimb;
extern StandardLimb gHorseBanditRightHindThighLimb;
extern StandardLimb gHorseBanditRightHindStifleLimb;
extern StandardLimb gHorseBanditRightHindCannonLimb;
extern StandardLimb gHorseBanditRightHindFootLimb;
extern void* gHorseBanditSkelLimbs[];
extern FlexSkeletonHeader gHorseBanditSkel;
extern s16 sHorseGallopAnimFrameData[];
extern JointIndex sHorseGallopAnimJointIndices[];
extern AnimationHeader gHorseGallopAnim;
extern s16 sHorseJumpLowAnimFrameData[];
extern JointIndex sHorseJumpLowAnimJointIndices[];
extern AnimationHeader gHorseJumpLowAnim;
extern s16 sHorseJumpHighAnimFrameData[];
extern JointIndex sHorseJumpHighAnimJointIndices[];
extern AnimationHeader gHorseJumpHighAnim;
extern s16 sHorseTrotAnimFrameData[];
extern JointIndex sHorseTrotAnimJointIndices[];
extern AnimationHeader gHorseTrotAnim;
extern s16 sHorseWhinnyAnimFrameData[];
extern JointIndex sHorseWhinnyAnimJointIndices[];
extern AnimationHeader gHorseWhinnyAnim;
extern s16 sHorseStopAnimFrameData[];
extern JointIndex sHorseStopAnimJointIndices[];
extern AnimationHeader gHorseStopAnim;
extern s16 sHorseIdleAnimFrameData[];
extern JointIndex sHorseIdleAnimJointIndices[];
extern AnimationHeader gHorseIdleAnim;
extern s16 sHorseShakeHeadAnimFrameData[];
extern JointIndex sHorseShakeHeadAnimJointIndices[];
extern AnimationHeader gHorseShakeHeadAnim;
extern s16 sHorseWalkAnimFrameData[];
extern JointIndex sHorseWalkAnimJointIndices[];
extern AnimationHeader gHorseWalkAnim;
extern Vtx object_haVtx_00D660[];
extern Gfx gDonkeyRightHindFootDL[];
extern Gfx gDonkeyRightHindCannonDL[];
extern Gfx gDonkeyRightHindStifleDL[];
extern Gfx gDonkeyRightHindThighDL[];
extern Gfx gDonkeyLeftHindFootDL[];
extern Gfx gDonkeyLeftHindCannonDL[];
extern Gfx gDonkeyLeftHindStifleDL[];
extern Gfx gDonkeyLeftHindThighDL[];
extern Gfx gDonkeyTailEndDL[];
extern Gfx gDonkeyTailMiddleDL[];
extern Gfx gDonkeyTailDockDL[];
extern Gfx gDonkeyPelvisDL[];
extern Gfx gDonkeyRightFrontFootDL[];
extern Gfx gDonkeyRightFrontCannonDL[];
extern Gfx gDonkeyRightFrontForearmDL[];
extern Gfx gDonkeyRightFrontLegRootDL[];
extern Gfx gDonkeyHeadDL[];
extern Gfx gDonkeyUpperNeckDL[];
extern Gfx gDonkeyLowerNeckDL[];
extern Gfx gDonkeyLeftFrontFootDL[];
extern Gfx gDonkeyLeftFrontCannonDL[];
extern Gfx gDonkeyLeftFrontForearmDL[];
extern Gfx gDonkeyLeftFrontLegRootDL[];
extern Gfx gDonkeyTorsoDL[];
extern u64 gDonkeyTLUT[];
extern u64 gDonkeyMouthTex[];
extern u64 gDonkeyHeadTex[];
extern u64 gDonkeyEyeTex[];
extern u64 gDonkeyManeTex[];
extern u64 gDonkeySkinTex[];
extern u64 gDonkeyHarnessTex[];
extern u64 gDonkeyTailAndFeetTex[];
extern StandardLimb gDonkeyRootLimb;
extern StandardLimb gDonkeyPelvisLimb;
extern StandardLimb gDonkeyTorsoLimb;
extern StandardLimb gDonkeyLeftFrontLegRootLimb;
extern StandardLimb gDonkeyLeftFrontForearmLimb;
extern StandardLimb gDonkeyLeftFrontCannonLimb;
extern StandardLimb gDonkeyLeftFrontFootLimb;
extern StandardLimb gDonkeyLowerNeckLimb;
extern StandardLimb gDonkeyUpperNeckLimb;
extern StandardLimb gDonkeyHeadLimb;
extern StandardLimb gDonkeyRightFrontLegRootLimb;
extern StandardLimb gDonkeyRightFrontForearmLimb;
extern StandardLimb gDonkeyRightFrontCannonLimb;
extern StandardLimb gDonkeyRightFrontFootLimb;
extern StandardLimb gDonkeyTailDockLimb;
extern StandardLimb gDonkeyTailMiddleLimb;
extern StandardLimb gDonkeyTailEndLimb;
extern StandardLimb gDonkeyLeftHindThighLimb;
extern StandardLimb gDonkeyLeftHindStifleLimb;
extern StandardLimb gDonkeyLeftHindCannonLimb;
extern StandardLimb gDonkeyLeftHindFootLimb;
extern StandardLimb gDonkeyRightHindThighLimb;
extern StandardLimb gDonkeyRightHindStifleLimb;
extern StandardLimb gDonkeyRightHindCannonLimb;
extern StandardLimb gDonkeyRightHindFootLimb;
extern void* gDonkeySkelLimbs[];
extern FlexSkeletonHeader gDonkeySkel;
#endif

View File

@ -21,7 +21,6 @@ void Sram_UpdateWriteToFlashDefault(SramContext* sramCtx) {
} }
} else if (sramCtx->status == 4) { } else if (sramCtx->status == 4) {
// @recomp Patched to check status instead of using a hardcoded wait. // @recomp Patched to check status instead of using a hardcoded wait.
recomp_printf("Status 4\n");
sramCtx->status = 0; sramCtx->status = 0;
} }
} }

View File

@ -733,8 +733,8 @@ void EnOsn_ChooseAction(EnOsn* this, PlayState* play) {
Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, OSN_ANIM_IDLE); Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, OSN_ANIM_IDLE);
if (!isSwitchFlagSet) { if (!isSwitchFlagSet) {
// @recomp Manual relocation, TODO remove when automated by the recompiler. // @recomp No need to relocate as this function is replaced, so the patch compilation will pick the new address.
this->actionFunc = (EnOsnActionFunc)actor_relocate(&this->actor, EnOsn_HandleCsAction); this->actionFunc = EnOsn_HandleCsAction;
} else { } else {
// @recomp Manual relocation, TODO remove when automated by the recompiler. // @recomp Manual relocation, TODO remove when automated by the recompiler.
this->actionFunc = (EnOsnActionFunc)actor_relocate(&this->actor, EnOsn_Idle); this->actionFunc = (EnOsnActionFunc)actor_relocate(&this->actor, EnOsn_Idle);
@ -916,3 +916,44 @@ void EnFall2_Draw(Actor* thisx, PlayState* play) {
} }
} }
} }
// @recomp Skip interpolation on item pickups the frame they're collected.
void func_800A6A40(EnItem00* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (this->getItemId != GI_NONE) {
if (!Actor_HasParent(&this->actor, play)) {
Actor_OfferGetItem(&this->actor, play, this->getItemId, 50.0f, 80.0f);
this->unk152++;
} else {
this->getItemId = GI_NONE;
}
}
if (this->unk152 == 0) {
Actor_Kill(&this->actor);
return;
}
this->actor.world.pos = player->actor.world.pos;
if (this->actor.params <= ITEM00_RUPEE_RED) {
this->actor.shape.rot.y += 0x3C0;
} else if (this->actor.params == ITEM00_RECOVERY_HEART) {
this->actor.shape.rot.y = 0;
}
this->actor.world.pos.y += (40.0f + (Math_SinS(this->unk152 * 15000) * (this->unk152 * 0.3f)));
if (LINK_IS_ADULT) {
this->actor.world.pos.y += 20.0f;
}
// @recomp Use custom flag 1 to check if this actor has been in this state before.
if (!actor_get_custom_flag_1(&this->actor)) {
recomp_printf("First frame picked up\n");
// It hasn't, so skip interpolation this frame and set custom flag 1.
actor_set_interpolation_skipped(&this->actor);
actor_set_custom_flag_1(&this->actor);
}
}

View File

@ -12,6 +12,8 @@ _ovl_daytelopSegmentBssEnd = 0x0;
sSceneEntranceTable = 0x801C5720; sSceneEntranceTable = 0x801C5720;
D_808DE5B0 = 0x808DE5B0; D_808DE5B0 = 0x808DE5B0;
sHappyMaskSalesmanAnimationInfo = 0x80AD22C0; sHappyMaskSalesmanAnimationInfo = 0x80AD22C0;
D_808890F0 = 0x808890F0;
D_8088911C = 0x8088911C;
/* Dummy addresses that get recompiled into function calls */ /* Dummy addresses that get recompiled into function calls */
recomp_puts = 0x8F000000; recomp_puts = 0x8F000000;

View File

@ -58,7 +58,8 @@ static inline u32 actor_transform_id(Actor* actor) {
typedef enum { typedef enum {
ACTOR_TRANSFORM_FLAG_INTERPOLATION_SKIPPED = 1 << 0, ACTOR_TRANSFORM_FLAG_INTERPOLATION_SKIPPED = 1 << 0,
} ActorTransformFlags; ACTOR_CUSTOM_FLAG_1 = 1 << 1,
} CustomActorFlags;
static inline u32 actor_get_interpolation_skipped(Actor* actor) { static inline u32 actor_get_interpolation_skipped(Actor* actor) {
return (actorIdByte2(actor) & ACTOR_TRANSFORM_FLAG_INTERPOLATION_SKIPPED) != 0; return (actorIdByte2(actor) & ACTOR_TRANSFORM_FLAG_INTERPOLATION_SKIPPED) != 0;
@ -72,6 +73,18 @@ static inline void actor_clear_interpolation_skipped(Actor* actor) {
actorIdByte2(actor) &= ~ACTOR_TRANSFORM_FLAG_INTERPOLATION_SKIPPED; actorIdByte2(actor) &= ~ACTOR_TRANSFORM_FLAG_INTERPOLATION_SKIPPED;
} }
static inline void actor_set_custom_flag_1(Actor* actor) {
actorIdByte2(actor) |= ACTOR_CUSTOM_FLAG_1;
}
static inline void actor_clear_custom_flag_1(Actor* actor) {
actorIdByte2(actor) &= ~ACTOR_CUSTOM_FLAG_1;
}
static inline bool actor_get_custom_flag_1(Actor* actor) {
return (actorIdByte2(actor) & ACTOR_CUSTOM_FLAG_1) != 0;
}
void force_camera_interpolation(); void force_camera_interpolation();
void force_camera_skip_interpolation(); void force_camera_skip_interpolation();