From 0a716c7875f753fc0ab1411bb08bb628bdcc7900 Mon Sep 17 00:00:00 2001 From: "Matthew D. Steele" Date: Sat, 31 Aug 2024 09:06:40 -0400 Subject: [PATCH] Always animate Alex NPC and player avatar when swimming --- src/actors/child.asm | 14 +++++++++++++- src/avatar.asm | 27 +++++++++++++++------------ src/cutscene.asm | 23 ++--------------------- src/dialog.asm | 33 +-------------------------------- 4 files changed, 31 insertions(+), 66 deletions(-) diff --git a/src/actors/child.asm b/src/actors/child.asm index e2573897..b471c546 100644 --- a/src/actors/child.asm +++ b/src/actors/child.asm @@ -31,6 +31,7 @@ .IMPORT Ram_ActorFlags_bObj_arr .IMPORT Ram_ActorState1_byte_arr .IMPORT Ram_Oam_sObj_arr64 +.IMPORTZP Zp_FrameCounter_u8 ;;;=========================================================================;;; @@ -79,9 +80,20 @@ kPaletteObjChild = 1 lda Ram_ActorState1_byte_arr, x stx T0 ; actor index tax ; eNpcChild value + ;; Special case: for eNpcChild::AlexSwimming1, automatically animate + ;; between AlexSwimming1 and AlexSwimming2. + cpx #eNpcChild::AlexSwimming1 + bne @setTiles + lda Zp_FrameCounter_u8 + adc #6 ; offset so swimming animation isn't synced with player avatar + and #$10 + bne @setTiles + ldx #eNpcChild::AlexSwimming2 + @setTiles: + ;; Set tile IDs for the objects. lda _Feet_u8_arr, x sta Ram_Oam_sObj_arr64 + .sizeof(sObj) * 1 + sObj::Tile_u8, y - adc #1 + add #1 sta Ram_Oam_sObj_arr64 + .sizeof(sObj) * 3 + sObj::Tile_u8, y lda _Head_u8_arr, x sta Ram_Oam_sObj_arr64 + .sizeof(sObj) * 0 + sObj::Tile_u8, y diff --git a/src/avatar.asm b/src/avatar.asm index a00f0869..16c14817 100644 --- a/src/avatar.asm +++ b/src/avatar.asm @@ -251,16 +251,7 @@ _SetPoseInAir: sta Zp_AvatarPose_eAvatar rts _SetPoseInWater: - ;; The player avatar is in water, so set its pose to Swimming. - lda Zp_FrameCounter_u8 - and #$10 - bne @swimming2 - @swimming1: - lda #eAvatar::Swimming1 - bne @setAvatarPose ; unconditional - @swimming2: - lda #eAvatar::Swimming2 - @setAvatarPose: + lda #eAvatar::Swimming1 ; animates automatically sta Zp_AvatarPose_eAvatar rts _SetPoseOnGround: @@ -847,11 +838,23 @@ _InAirReverseGravity: @notInvincible: _DrawObjects: jsr FuncA_Objects_SetShapePosToAvatarCenter - lda Zp_AvatarPose_eAvatar + ;; If the player avatar is hidden, don't draw it. + ldx Zp_AvatarPose_eAvatar .assert eAvatar::Hidden = 0, error beq _Done + ;; Special case: for eAvatar::Swimming1, automatically animate between + ;; Swimming1 and Swimming2. + cpx #eAvatar::Swimming1 + bne @drawPose + lda Zp_FrameCounter_u8 + and #$10 + bne @drawPose + ldx #eAvatar::Swimming2 + @drawPose: + ;; Draw objects for the player avatar. + txa ; eAvatar value mul #4 - tax + tax ; byte index into _Tiles_u8_arr4_arr lda Zp_AvatarFlags_bObj ; param: object flags jsr FuncA_Objects_Alloc2x2Shape ; preserves X, returns C and Y bcs _Done diff --git a/src/cutscene.asm b/src/cutscene.asm index 0cb59688..28e6cdb8 100644 --- a/src/cutscene.asm +++ b/src/cutscene.asm @@ -918,17 +918,7 @@ _MoveByYA: ;;; @preserve X, Y, T0+ .PROC FuncA_Cutscene_AnimateAvatarSwimming jsr FuncA_Cutscene_FaceAvatarTowardsN -_AnimatePose: - lda Zp_FrameCounter_u8 - and #$10 - beq @swim2 - @swim1: - lda #eAvatar::Swimming1 - .assert eAvatar::Swimming1 > 0, error - bne @setPose ; unconditional - @swim2: - lda #eAvatar::Swimming2 - @setPose: + lda #eAvatar::Swimming1 ; animates automatically sta Zp_AvatarPose_eAvatar rts .ENDPROC @@ -964,17 +954,8 @@ _AnimatePose: jsr FuncA_Cutscene_SetActorFlipHFromN ; preserves X, Y and T0+ lda #$ff sta Ram_ActorState2_byte_arr, x -_AnimatePose: - lda Zp_FrameCounter_u8 - and #$10 - beq @swim2 - @swim1: + ;; Set pose to AlexSwimming1; this will animate automatically. lda #eNpcChild::AlexSwimming1 - .assert eNpcChild::AlexSwimming1 > 0, error - bne @setState ; unconditional - @swim2: - lda #eNpcChild::AlexSwimming2 - @setState: sta Ram_ActorState1_byte_arr, x rts .ENDPROC diff --git a/src/dialog.asm b/src/dialog.asm index beff941c..bb9147da 100644 --- a/src/dialog.asm +++ b/src/dialog.asm @@ -390,7 +390,7 @@ _GameLoop: jsr_prga FuncA_Objects_DrawDialogCursorAndObjectsForRoom jsr Func_ClearRestOfOamAndProcessFrame _Tick: - jsr_prga FuncA_Dialog_TickAvatarAndText ; returns C, Z, T2, and T1T0 + jsr_prga FuncA_Dialog_TickText ; returns C, Z, T2, and T1T0 bcs Main_Dialog_CloseWindow beq @done jsr FuncM_CopyDialogText @@ -698,35 +698,6 @@ _Done: rts .ENDPROC -;;; Animates the player avatar as needed during dialog. In particular, if the -;;; avatar is swimming, updates the swimming animation. -.PROC FuncA_Dialog_TickAvatar - bit Zp_AvatarState_bAvatar - .assert bAvatar::Swimming = bProc::Overflow, error - bvc _Return ; player avatar is not swimming -_SetSwimmingPose: - ldy #eAvatar::Swimming2 - lda Zp_FrameCounter_u8 - and #$10 - bne @setAvatarPose - @swimming1: - ldy #eAvatar::Swimming1 - @setAvatarPose: - sty Zp_AvatarPose_eAvatar -_Return: - rts -.ENDPROC - -;;; Calls FuncA_Dialog_TickAvatar and then FuncA_Dialog_TickText. -;;; @return C Set if dialog is finished and the window should be closed. -;;; @return Z Cleared if we should copy the next pane of dialog text. -;;; @return T2 The PRGA bank number that contains the next dialog text. -;;; @return T1T0 A pointer to the start of the next dialog text. -.PROC FuncA_Dialog_TickAvatarAndText - jsr FuncA_Dialog_TickAvatar - fall FuncA_Dialog_TickText ; returns C, Z, T2, and T1T0 -.ENDPROC - ;;; Updates the dialog text based on joypad input and animates the dialog ;;; portrait appropriately. The return values indicate whether dialog should ;;; end or continue, and whether it's time to copy the next pane of dialog @@ -927,7 +898,6 @@ _UpdateDialogPointer: ;;; is closing. ;;; @return C Set if the window is now fully scrolled out. .PROC FuncA_Dialog_ScrollWindowDown - jsr FuncA_Dialog_TickAvatar _ScrollWindow: lda Zp_WindowTop_u8 add #kDialogWindowScrollSpeed @@ -955,7 +925,6 @@ _FullyClosed: ;;; this each frame when the window is opening. ;;; @return C Set if the window is now fully scrolled in. .PROC FuncA_Dialog_ScrollWindowUp - jsr FuncA_Dialog_TickAvatar _AdjustAvatarHorz: ;; Only adjust the player avatar's position if this dialog was started by ;; using a device, rather than from a cutscene.