mirror of
				https://github.com/Zelda64Recomp/Zelda64Recomp.git
				synced 2025-10-30 08:03:03 +00:00 
			
		
		
		
	Fix all the interpolation glitches in the Gibdo Mask cutscene (#641)
This commit is contained in:
		
							parent
							
								
									3aea1bee48
								
							
						
					
					
						commit
						b035cdb605
					
				
					 8 changed files with 442 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -76,6 +76,17 @@ void camera_post_play_update(PlayState* play) {
 | 
			
		|||
            if (force_interpolation) {
 | 
			
		||||
                force_camera_interpolation();
 | 
			
		||||
            }
 | 
			
		||||
            // Dedicated section for workarounds where the heuristic fails to detect small camera teleports.
 | 
			
		||||
            bool force_no_interpolation = false;
 | 
			
		||||
 | 
			
		||||
            // Music Box House. The camera gets teleported by a very small amount when Link gets the Gibdo mask.
 | 
			
		||||
            if (play->sceneId == SCENE_MUSICHOUSE && play->csCtx.scriptIndex == 2 && play->csCtx.curFrame == 525 && active_cam->setting == CAM_SET_FREE0) {
 | 
			
		||||
                force_no_interpolation = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (force_no_interpolation) {
 | 
			
		||||
                force_camera_skip_interpolation();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,3 +14,33 @@ symbols = [
 | 
			
		|||
    { name = "FileSelect_Init_NORELOCATE", vram = 0x80813C98 },
 | 
			
		||||
    { name = "DayTelop_Init_NORELOCATE", vram = 0x80815820 },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[section]]
 | 
			
		||||
name = "..ovl_En_Hg"
 | 
			
		||||
rom = 0x01034170
 | 
			
		||||
vram = 0x80BCF1D0
 | 
			
		||||
size = 0x10E0
 | 
			
		||||
 | 
			
		||||
symbols = [
 | 
			
		||||
    { name = "sPamelasFatherGibdoAnimationInfo", vram = 0x80bd0008 },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[section]]
 | 
			
		||||
name = "..ovl_En_Hgo"
 | 
			
		||||
rom = 0x01035250
 | 
			
		||||
vram = 0x80BD02B0
 | 
			
		||||
size = 0xF30
 | 
			
		||||
 | 
			
		||||
symbols = [
 | 
			
		||||
    { name = "sPamelasFatherHumanAnimationInfo", vram = 0x80BD0EA0 },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[section]]
 | 
			
		||||
name = "..ovl_En_Pamera"
 | 
			
		||||
rom = 0x0103D250
 | 
			
		||||
vram = 0x80BD82B0
 | 
			
		||||
size = 0x2780
 | 
			
		||||
 | 
			
		||||
symbols = [
 | 
			
		||||
    { name = "sPamelaAnimationInfo", vram = 0x80BDA4B8 },
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
typedef enum PamelasFatherGibdoLimb {
 | 
			
		||||
    /* 0x00 */ PAMELAS_FATHER_GIBDO_LIMB_NONE,
 | 
			
		||||
    /* 0x01 */ PAMELAS_FATHER_GIBDO_LIMB_ROOT,
 | 
			
		||||
    /* 0x02 */ PAMELAS_FATHER_GIBDO_LIMB_ABDOMEN,
 | 
			
		||||
    /* 0x03 */ PAMELAS_FATHER_GIBDO_LIMB_CHEST,
 | 
			
		||||
    /* 0x04 */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_UPPER_ARM,
 | 
			
		||||
    /* 0x05 */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_FOREARM,
 | 
			
		||||
    /* 0x06 */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_HAND,
 | 
			
		||||
    /* 0x07 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_UPPER_ARM,
 | 
			
		||||
    /* 0x08 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_FOREARM,
 | 
			
		||||
    /* 0x09 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_HAND,
 | 
			
		||||
    /* 0x0A */ PAMELAS_FATHER_GIBDO_LIMB_EYEBROWS,
 | 
			
		||||
    /* 0x0B */ PAMELAS_FATHER_GIBDO_LIMB_HEAD,
 | 
			
		||||
    /* 0x0C */ PAMELAS_FATHER_GIBDO_LIMB_PELVIS,
 | 
			
		||||
    /* 0x0D */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_THIGH,
 | 
			
		||||
    /* 0x0E */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_SHIN,
 | 
			
		||||
    /* 0x0F */ PAMELAS_FATHER_GIBDO_LIMB_LEFT_FOOT,
 | 
			
		||||
    /* 0x10 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_THIGH,
 | 
			
		||||
    /* 0x11 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_SHIN,
 | 
			
		||||
    /* 0x12 */ PAMELAS_FATHER_GIBDO_LIMB_RIGHT_FOOT,
 | 
			
		||||
    /* 0x13 */ PAMELAS_FATHER_GIBDO_LIMB_MAX
 | 
			
		||||
} PamelasFatherGibdoLimb;
 | 
			
		||||
 | 
			
		||||
typedef enum PamelasFatherHumanLimb {
 | 
			
		||||
    /* 0x00 */ PAMELAS_FATHER_HUMAN_LIMB_NONE,
 | 
			
		||||
    /* 0x01 */ PAMELAS_FATHER_HUMAN_LIMB_ROOT,
 | 
			
		||||
    /* 0x02 */ PAMELAS_FATHER_HUMAN_LIMB_ABDOMEN,
 | 
			
		||||
    /* 0x03 */ PAMELAS_FATHER_HUMAN_LIMB_CHEST,
 | 
			
		||||
    /* 0x04 */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_UPPER_ARM,
 | 
			
		||||
    /* 0x05 */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_FOREARM,
 | 
			
		||||
    /* 0x06 */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_HAND,
 | 
			
		||||
    /* 0x07 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_UPPER_ARM,
 | 
			
		||||
    /* 0x08 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_FOREARM,
 | 
			
		||||
    /* 0x09 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_HAND,
 | 
			
		||||
    /* 0x0A */ PAMELAS_FATHER_HUMAN_LIMB_EYEBROWS,
 | 
			
		||||
    /* 0x0B */ PAMELAS_FATHER_HUMAN_LIMB_HEAD,
 | 
			
		||||
    /* 0x0C */ PAMELAS_FATHER_HUMAN_LIMB_PELVIS,
 | 
			
		||||
    /* 0x0D */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_THIGH,
 | 
			
		||||
    /* 0x0E */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_SHIN,
 | 
			
		||||
    /* 0x0F */ PAMELAS_FATHER_HUMAN_LIMB_LEFT_FOOT,
 | 
			
		||||
    /* 0x10 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_THIGH,
 | 
			
		||||
    /* 0x11 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_SHIN,
 | 
			
		||||
    /* 0x12 */ PAMELAS_FATHER_HUMAN_LIMB_RIGHT_FOOT,
 | 
			
		||||
    /* 0x13 */ PAMELAS_FATHER_HUMAN_LIMB_MAX
 | 
			
		||||
} PamelasFatherHumanLimb;
 | 
			
		||||
							
								
								
									
										26
									
								
								patches/dummy_headers/objects/object_pamera/object_pamera.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								patches/dummy_headers/objects/object_pamera/object_pamera.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
typedef enum PamelaLimb {
 | 
			
		||||
    /* 0x00 */ PAMELA_LIMB_NONE,
 | 
			
		||||
    /* 0x01 */ PAMELA_LIMB_ROOT,
 | 
			
		||||
    /* 0x02 */ PAMELA_LIMB_UPPER_BODY_ROOT,
 | 
			
		||||
    /* 0x03 */ PAMELA_LIMB_LEFT_UPPER_ARM,
 | 
			
		||||
    /* 0x04 */ PAMELA_LIMB_LEFT_FOREARM,
 | 
			
		||||
    /* 0x05 */ PAMELA_LIMB_LEFT_HAND,
 | 
			
		||||
    /* 0x06 */ PAMELA_LIMB_RIGHT_UPPER_ARM,
 | 
			
		||||
    /* 0x07 */ PAMELA_LIMB_RIGHT_FOREARM,
 | 
			
		||||
    /* 0x08 */ PAMELA_LIMB_RIGHT_HAND,
 | 
			
		||||
    /* 0x09 */ PAMELA_LIMB_HEAD,
 | 
			
		||||
    /* 0x0A */ PAMELA_LIMB_HAIR_END,
 | 
			
		||||
    /* 0x0B */ PAMELA_LIMB_CHEST,
 | 
			
		||||
    /* 0x0C */ PAMELA_LIMB_NECK,
 | 
			
		||||
    /* 0x0D */ PAMELA_LIMB_LEFT_THIGH,
 | 
			
		||||
    /* 0x0E */ PAMELA_LIMB_LEFT_LEG,
 | 
			
		||||
    /* 0x0F */ PAMELA_LIMB_LEFT_FOOT,
 | 
			
		||||
    /* 0x10 */ PAMELA_LIMB_RIGHT_THIGH,
 | 
			
		||||
    /* 0x11 */ PAMELA_LIMB_RIGHT_LEG,
 | 
			
		||||
    /* 0x12 */ PAMELA_LIMB_RIGHT_FOOT,
 | 
			
		||||
    /* 0x13 */ PAMELA_LIMB_FRONT_DRESS,
 | 
			
		||||
    /* 0x14 */ PAMELA_LIMB_BACK_DRESS,
 | 
			
		||||
    /* 0x15 */ PAMELA_LIMB_ABDOMEN,
 | 
			
		||||
    /* 0x16 */ PAMELA_LIMB_PELVIS,
 | 
			
		||||
    /* 0x17 */ PAMELA_LIMB_MAX
 | 
			
		||||
} PamelaLimb;
 | 
			
		||||
							
								
								
									
										123
									
								
								patches/gibdo_mask_cutscene_father_gibdo.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								patches/gibdo_mask_cutscene_father_gibdo.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,123 @@
 | 
			
		|||
#include "patches.h"
 | 
			
		||||
#include "transform_ids.h"
 | 
			
		||||
#include "overlays/actors/ovl_En_Hg/z_en_hg.h"
 | 
			
		||||
 | 
			
		||||
extern AnimationInfo sPamelasFatherGibdoAnimationInfo[];
 | 
			
		||||
extern void EnHg_SetupWait(EnHg* this);
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    /* 0 */ HG_ANIM_IDLE,
 | 
			
		||||
    /* 1 */ HG_ANIM_LURCH_FORWARD,
 | 
			
		||||
    /* 2 */ HG_ANIM_RECOIL,
 | 
			
		||||
    /* 3 */ HG_ANIM_LEAN_FORWARD,
 | 
			
		||||
    /* 4 */ HG_ANIM_REACH_FORWARD,
 | 
			
		||||
    /* 5 */ HG_ANIM_CURL_UP,
 | 
			
		||||
    /* 6 */ HG_ANIM_CROUCHED_PANIC,
 | 
			
		||||
    /* 7 */ HG_ANIM_PANIC,
 | 
			
		||||
    /* 8 */ HG_ANIM_MAX
 | 
			
		||||
} HgAnimation;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    /* 0 */ HG_CS_FIRST_ENCOUNTER,
 | 
			
		||||
    /* 1 */ HG_CS_GET_MASK,
 | 
			
		||||
    /* 2 */ HG_CS_SUBSEQUENT_ENCOUNTER,
 | 
			
		||||
    /* 3 */ HG_CS_SONG_OF_HEALING
 | 
			
		||||
} HgCsIndex;
 | 
			
		||||
 | 
			
		||||
// @recomp Skip interpolation when the animations change during the cutscene, as the
 | 
			
		||||
// animation changes are meant to happen at the same time as the camera cuts.
 | 
			
		||||
void EnHg_HandleCutscene(EnHg* this, PlayState* play) {
 | 
			
		||||
    if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_484)) {
 | 
			
		||||
        s32 cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_484);
 | 
			
		||||
 | 
			
		||||
        if (this->csIdList[3] != play->csCtx.actorCues[cueChannel]->id) {
 | 
			
		||||
            this->csIdList[3] = play->csCtx.actorCues[cueChannel]->id;
 | 
			
		||||
            switch (play->csCtx.actorCues[cueChannel]->id) {
 | 
			
		||||
                case 1:
 | 
			
		||||
                    this->animIndex = HG_ANIM_IDLE;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_IDLE);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 2:
 | 
			
		||||
                    this->csIdList[2] = 0;
 | 
			
		||||
                    this->animIndex = HG_ANIM_LEAN_FORWARD;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_LEAN_FORWARD);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 3:
 | 
			
		||||
                    this->csIdList[2] = 0;
 | 
			
		||||
                    this->animIndex = HG_ANIM_CURL_UP;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_CURL_UP);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 4:
 | 
			
		||||
                    this->csIdList[2] = 0;
 | 
			
		||||
                    this->animIndex = HG_ANIM_PANIC;
 | 
			
		||||
                    if ((this->csIdIndex == HG_CS_GET_MASK) || (this->csIdIndex == HG_CS_SONG_OF_HEALING)) {
 | 
			
		||||
                        Audio_PlaySfx_2(NA_SE_EN_HALF_REDEAD_TRANS);
 | 
			
		||||
                    }
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_PANIC);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 5:
 | 
			
		||||
                    this->animIndex = HG_ANIM_LURCH_FORWARD;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_LURCH_FORWARD);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 6:
 | 
			
		||||
                    SET_WEEKEVENTREG(WEEKEVENTREG_75_20);
 | 
			
		||||
                    Actor_Kill(&this->actor);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            actor_set_interpolation_skipped(&this->actor);
 | 
			
		||||
        } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
 | 
			
		||||
            switch (this->animIndex) {
 | 
			
		||||
                case HG_ANIM_LEAN_FORWARD:
 | 
			
		||||
                    this->animIndex = HG_ANIM_REACH_FORWARD;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_REACH_FORWARD);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case HG_ANIM_CURL_UP:
 | 
			
		||||
                    this->animIndex = HG_ANIM_CROUCHED_PANIC;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherGibdoAnimationInfo, HG_ANIM_CROUCHED_PANIC);
 | 
			
		||||
                    break;
 | 
			
		||||
            
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            actor_set_interpolation_skipped(&this->actor);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (this->animIndex) {
 | 
			
		||||
            case HG_ANIM_LEAN_FORWARD:
 | 
			
		||||
            case HG_ANIM_REACH_FORWARD:
 | 
			
		||||
                Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_HALF_REDEAD_LOOP - SFX_FLAG);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case HG_ANIM_CURL_UP:
 | 
			
		||||
            case HG_ANIM_CROUCHED_PANIC:
 | 
			
		||||
                Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_HALF_REDEAD_SCREAME - SFX_FLAG);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case HG_ANIM_PANIC:
 | 
			
		||||
                if ((this->csIdIndex == HG_CS_FIRST_ENCOUNTER) || (this->csIdIndex == HG_CS_SUBSEQUENT_ENCOUNTER)) {
 | 
			
		||||
                    Actor_PlaySfx_Flagged(&this->actor, NA_SE_EN_HALF_REDEAD_SCREAME - SFX_FLAG);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Cutscene_ActorTranslateAndYaw(&this->actor, play, cueChannel);
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    } else if (play->csCtx.state == CS_STATE_IDLE) {
 | 
			
		||||
        EnHg_SetupWait(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this->csIdList[3] = 99;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										107
									
								
								patches/gibdo_mask_cutscene_father_human.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								patches/gibdo_mask_cutscene_father_human.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,107 @@
 | 
			
		|||
#include "patches.h"
 | 
			
		||||
#include "transform_ids.h"
 | 
			
		||||
#include "overlays/actors/ovl_En_Hgo/z_en_hgo.h"
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    /* 0 */ HGO_ANIM_ARMS_FOLDED,
 | 
			
		||||
    /* 1 */ HGO_ANIM_ASTONISHED,
 | 
			
		||||
    /* 2 */ HGO_ANIM_KNEEL_DOWN_AND_HUG,
 | 
			
		||||
    /* 3 */ HGO_ANIM_CONSOLE,
 | 
			
		||||
    /* 4 */ HGO_ANIM_CONSOLE_HEAD_UP,
 | 
			
		||||
    /* 5 */ HGO_ANIM_REACH_DOWN_TO_LIFT,
 | 
			
		||||
    /* 6 */ HGO_ANIM_TOSS,
 | 
			
		||||
    /* 7 */ HGO_ANIM_MAX
 | 
			
		||||
} HgoAnimation;
 | 
			
		||||
 | 
			
		||||
extern AnimationInfo sPamelasFatherHumanAnimationInfo[];
 | 
			
		||||
extern void EnHgo_Draw(Actor* thisx, PlayState* play);
 | 
			
		||||
extern void EnHgo_DoNothing(EnHgo* this, PlayState* play);
 | 
			
		||||
extern void EnHgo_SetupInitCollision(EnHgo* this);
 | 
			
		||||
 | 
			
		||||
// @recomp Skip interpolation when the animations change during the cutscene, as the
 | 
			
		||||
// animation changes are meant to happen at the same time as the camera cuts.
 | 
			
		||||
RECOMP_PATCH s32 EnHgo_HandleCsAction(EnHgo* this, PlayState* play) {
 | 
			
		||||
    s32 cueChannel;
 | 
			
		||||
 | 
			
		||||
    if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_486)) {
 | 
			
		||||
        cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_486);
 | 
			
		||||
        if (this->cueId != play->csCtx.actorCues[cueChannel]->id) {
 | 
			
		||||
            this->cueId = play->csCtx.actorCues[cueChannel]->id;
 | 
			
		||||
            switch (play->csCtx.actorCues[cueChannel]->id) {
 | 
			
		||||
                case 1:
 | 
			
		||||
                    this->animIndex = HGO_ANIM_ARMS_FOLDED;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_ARMS_FOLDED);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 2:
 | 
			
		||||
                    this->actor.draw = EnHgo_Draw;
 | 
			
		||||
                    this->animIndex = HGO_ANIM_ASTONISHED;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_ASTONISHED);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 3:
 | 
			
		||||
                    this->animIndex = HGO_ANIM_KNEEL_DOWN_AND_HUG;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_KNEEL_DOWN_AND_HUG);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 4:
 | 
			
		||||
                    this->animIndex = HGO_ANIM_CONSOLE;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_CONSOLE);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 5:
 | 
			
		||||
                    this->animIndex = HGO_ANIM_CONSOLE_HEAD_UP;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_CONSOLE_HEAD_UP);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 6:
 | 
			
		||||
                    this->animIndex = HGO_ANIM_REACH_DOWN_TO_LIFT;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_REACH_DOWN_TO_LIFT);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            actor_set_interpolation_skipped(&this->actor);
 | 
			
		||||
        } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
 | 
			
		||||
            switch (this->animIndex) {
 | 
			
		||||
                case HGO_ANIM_ASTONISHED:
 | 
			
		||||
                    if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && !this->isInCutscene) {
 | 
			
		||||
                        this->isInCutscene = true;
 | 
			
		||||
                        if ((gSaveContext.sceneLayer == 0) &&
 | 
			
		||||
                            ((play->csCtx.scriptIndex == 2) || (play->csCtx.scriptIndex == 4))) {
 | 
			
		||||
                            Actor_PlaySfx(&this->actor, NA_SE_VO_GBVO02);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case HGO_ANIM_KNEEL_DOWN_AND_HUG:
 | 
			
		||||
                    this->animIndex = HGO_ANIM_CONSOLE;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_CONSOLE);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case HGO_ANIM_REACH_DOWN_TO_LIFT:
 | 
			
		||||
                    this->animIndex = HGO_ANIM_TOSS;
 | 
			
		||||
                    Actor_ChangeAnimationByInfo(&this->skelAnime, sPamelasFatherHumanAnimationInfo, HGO_ANIM_TOSS);
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
                
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Cutscene_ActorTranslateAndYaw(&this->actor, play, cueChannel);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((play->csCtx.state == CS_STATE_IDLE) && CHECK_WEEKEVENTREG(WEEKEVENTREG_75_20) &&
 | 
			
		||||
        (this->actionFunc == EnHgo_DoNothing)) {
 | 
			
		||||
        this->actor.shape.rot.y = this->actor.world.rot.y;
 | 
			
		||||
        Actor_Spawn(&play->actorCtx, play, ACTOR_ELF_MSG2, this->actor.focus.pos.x, this->actor.focus.pos.y,
 | 
			
		||||
                    this->actor.focus.pos.z, 7, 0, 0, 0x7F5A);
 | 
			
		||||
        EnHgo_SetupInitCollision(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this->cueId = 99;
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								patches/gibdo_mask_cutscene_mask.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								patches/gibdo_mask_cutscene_mask.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
#include "patches.h"
 | 
			
		||||
#include "transform_ids.h"
 | 
			
		||||
#include "overlays/actors/ovl_Dm_Char05/z_dm_char05.h"
 | 
			
		||||
 | 
			
		||||
extern void func_80AADF54(PlayState* play, DmChar05* this);
 | 
			
		||||
 | 
			
		||||
// @recomp Patched to avoid an interpolation glitch in Pamela's dad's cutscene
 | 
			
		||||
// that happens when the mask is meant to teleport offscreen.
 | 
			
		||||
RECOMP_PATCH void func_80AADB4C(Actor* thisx, PlayState* play) {
 | 
			
		||||
    DmChar05* this = (DmChar05*)thisx;
 | 
			
		||||
    if (this->unk_18E == 0) {
 | 
			
		||||
        if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_518) &&
 | 
			
		||||
            (play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_518)]->id != 1)) {
 | 
			
		||||
            // @recomp During this cue the mask does nothing other than teleport offscreen and stay still,
 | 
			
		||||
            // so we can just skip interpolation the entire time.
 | 
			
		||||
            if (play->csCtx.actorCues[Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_518)]->id == 3) {
 | 
			
		||||
                actor_set_interpolation_skipped(thisx);
 | 
			
		||||
            }
 | 
			
		||||
            Gfx_SetupDL25_Opa(play->state.gfxCtx);
 | 
			
		||||
            SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
 | 
			
		||||
                                  this->skelAnime.dListCount, NULL, NULL, &this->actor);
 | 
			
		||||
        }
 | 
			
		||||
    } else if (this->unk_18E == 1) {
 | 
			
		||||
        func_80AADF54(play, this);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										74
									
								
								patches/gibdo_mask_cutscene_pamela.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								patches/gibdo_mask_cutscene_pamela.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,74 @@
 | 
			
		|||
#include "patches.h"
 | 
			
		||||
#include "transform_ids.h"
 | 
			
		||||
#include "overlays/actors/ovl_En_Pamera/z_en_pamera.h"
 | 
			
		||||
 | 
			
		||||
extern void EnPamera_Draw(Actor* thisx, PlayState* play);
 | 
			
		||||
extern void func_80BD9E88(EnPamera* this);
 | 
			
		||||
extern void func_80BD9EE0(EnPamera* this);
 | 
			
		||||
extern void func_80BDA038(EnPamera* this);
 | 
			
		||||
extern void func_80BDA0A0(EnPamera* this);
 | 
			
		||||
extern void func_80BDA170(EnPamera* this);
 | 
			
		||||
extern void func_80BDA288(EnPamera* this);
 | 
			
		||||
extern void func_80BD994C(EnPamera* this, PlayState* play);
 | 
			
		||||
extern void EnPamera_HandleDialogue(EnPamera* this, PlayState* play);
 | 
			
		||||
extern void func_80BD9904(EnPamera* this);
 | 
			
		||||
extern void func_80BD9E60(EnPamera* this);
 | 
			
		||||
 | 
			
		||||
// @recomp Skip interpolation when the animations change during the cutscene, as the
 | 
			
		||||
// animation changes are meant to happen at the same time as the camera cuts.
 | 
			
		||||
RECOMP_PATCH s32 func_80BD9CB8(EnPamera* this, PlayState* play) {
 | 
			
		||||
    s32 cueChannel;
 | 
			
		||||
 | 
			
		||||
    if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_485)) {
 | 
			
		||||
        cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_485);
 | 
			
		||||
        if (this->cueId != play->csCtx.actorCues[cueChannel]->id) {
 | 
			
		||||
            this->cueId = play->csCtx.actorCues[cueChannel]->id;
 | 
			
		||||
 | 
			
		||||
            switch (play->csCtx.actorCues[cueChannel]->id) {
 | 
			
		||||
                case 1:
 | 
			
		||||
                    func_80BD9E88(this);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 2:
 | 
			
		||||
                    if (this->actor.draw == NULL) {
 | 
			
		||||
                        this->actor.draw = EnPamera_Draw;
 | 
			
		||||
                        this->actor.flags |= ACTOR_FLAG_TARGETABLE;
 | 
			
		||||
                    }
 | 
			
		||||
                    func_80BD9EE0(this);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 3:
 | 
			
		||||
                    func_80BDA038(this);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 4:
 | 
			
		||||
                    func_80BDA0A0(this);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 5:
 | 
			
		||||
                    func_80BDA170(this);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 6:
 | 
			
		||||
                    func_80BDA288(this);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            actor_set_interpolation_skipped(&this->actor);
 | 
			
		||||
        }
 | 
			
		||||
        Cutscene_ActorTranslateAndYaw(&this->actor, play, cueChannel);
 | 
			
		||||
        this->setupFunc(this, play);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    if ((play->csCtx.state == CS_STATE_IDLE) && CHECK_WEEKEVENTREG(WEEKEVENTREG_75_20)) {
 | 
			
		||||
        if ((this->actionFunc != func_80BD994C) && (this->actionFunc != EnPamera_HandleDialogue)) {
 | 
			
		||||
            this->actor.shape.rot.y = this->actor.world.rot.y;
 | 
			
		||||
            func_80BD9904(this);
 | 
			
		||||
            func_80BD9E60(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    this->cueId = 99;
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue