Skip to content

Commit

Permalink
Start implementing ghost baddie actors for the shadow boss
Browse files Browse the repository at this point in the history
  • Loading branch information
mdsteele committed Jun 20, 2024
1 parent 2c7a806 commit 377d1ae
Show file tree
Hide file tree
Showing 8 changed files with 343 additions and 13 deletions.
16 changes: 16 additions & 0 deletions src/actor.asm
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
.IMPORT FuncA_Actor_TickBadFirefly
.IMPORT FuncA_Actor_TickBadFish
.IMPORT FuncA_Actor_TickBadFlydrop
.IMPORT FuncA_Actor_TickBadGhostMermaid
.IMPORT FuncA_Actor_TickBadGhostOrc
.IMPORT FuncA_Actor_TickBadGooGreen
.IMPORT FuncA_Actor_TickBadGooRed
.IMPORT FuncA_Actor_TickBadGronta
Expand Down Expand Up @@ -83,6 +85,8 @@
.IMPORT FuncA_Objects_DrawActorBadFirefly
.IMPORT FuncA_Objects_DrawActorBadFish
.IMPORT FuncA_Objects_DrawActorBadFlydrop
.IMPORT FuncA_Objects_DrawActorBadGhostMermaid
.IMPORT FuncA_Objects_DrawActorBadGhostOrc
.IMPORT FuncA_Objects_DrawActorBadGooGreen
.IMPORT FuncA_Objects_DrawActorBadGooRed
.IMPORT FuncA_Objects_DrawActorBadGronta
Expand Down Expand Up @@ -484,6 +488,8 @@ _NoHit:
d_byte BadFirefly, 6
d_byte BadFish, 6
d_byte BadFlydrop, 6
d_byte BadGhostMermaid, 13
d_byte BadGhostOrc, kOrcBoundingBoxUp
d_byte BadGooGreen, kBadGooRadius
d_byte BadGooRed, kBadGooRadius
d_byte BadGronta, kOrcBoundingBoxUp
Expand Down Expand Up @@ -544,6 +550,8 @@ _NoHit:
d_byte BadFirefly, 8
d_byte BadFish, 4
d_byte BadFlydrop, 6
d_byte BadGhostMermaid, 7
d_byte BadGhostOrc, kOrcBoundingBoxDown
d_byte BadGooGreen, kBadGooRadius
d_byte BadGooRed, kBadGooRadius
d_byte BadGronta, kOrcBoundingBoxDown
Expand Down Expand Up @@ -604,6 +612,8 @@ _NoHit:
d_byte BadFirefly, 6
d_byte BadFish, 6
d_byte BadFlydrop, 6
d_byte BadGhostMermaid, 6
d_byte BadGhostOrc, kOrcBoundingBoxSide
d_byte BadGooGreen, kBadGooRadius
d_byte BadGooRed, kBadGooRadius
d_byte BadGronta, kOrcBoundingBoxSide
Expand Down Expand Up @@ -732,6 +742,8 @@ _TypeSpecificTick:
d_entry table, BadFirefly, FuncA_Actor_TickBadFirefly
d_entry table, BadFish, FuncA_Actor_TickBadFish
d_entry table, BadFlydrop, FuncA_Actor_TickBadFlydrop
d_entry table, BadGhostMermaid, FuncA_Actor_TickBadGhostMermaid
d_entry table, BadGhostOrc, FuncA_Actor_TickBadGhostOrc
d_entry table, BadGooGreen, FuncA_Actor_TickBadGooGreen
d_entry table, BadGooRed, FuncA_Actor_TickBadGooRed
d_entry table, BadGronta, FuncA_Actor_TickBadGronta
Expand Down Expand Up @@ -896,6 +908,8 @@ _Finish:
d_entry table, BadFirefly, FuncA_Room_InitActorBadFirefly
d_entry table, BadFish, Func_InitActorWithFlags
d_entry table, BadFlydrop, FuncA_Room_InitActorBadFlydrop
d_entry table, BadGhostMermaid, Func_InitActorWithState1
d_entry table, BadGhostOrc, Func_InitActorWithState1
d_entry table, BadGooGreen, Func_InitActorWithFlags
d_entry table, BadGooRed, FuncA_Room_InitActorBadGooRed
d_entry table, BadGronta, Func_InitActorBadGronta
Expand Down Expand Up @@ -985,6 +999,8 @@ _Finish:
d_entry table, BadFirefly, FuncA_Objects_DrawActorBadFirefly
d_entry table, BadFish, FuncA_Objects_DrawActorBadFish
d_entry table, BadFlydrop, FuncA_Objects_DrawActorBadFlydrop
d_entry table, BadGhostMermaid, FuncA_Objects_DrawActorBadGhostMermaid
d_entry table, BadGhostOrc, FuncA_Objects_DrawActorBadGhostOrc
d_entry table, BadGooGreen, FuncA_Objects_DrawActorBadGooGreen
d_entry table, BadGooRed, FuncA_Objects_DrawActorBadGooRed
d_entry table, BadGronta, FuncA_Objects_DrawActorBadGronta
Expand Down
4 changes: 3 additions & 1 deletion src/actor.inc
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ kMaxActors = 16
BadFirefly ; flies up and down, and shoots horizontally
BadFish ; swims back and forth in water
BadFlydrop ; flies left/right randomly, and drops acid
BadGhostMermaid ; part of the shadow boss
BadGhostOrc ; part of the shadow boss
BadGooGreen ; squishes in place
BadGooRed ; squishes back and forth
BadGronta
BadGronta ; the final boss
BadGrub ; crawls left/right on a floor
BadHotheadHorz ; crawls around a platform, and can drop fire
BadHotheadVert ; crawls around a platform, and can drop fire
Expand Down
247 changes: 247 additions & 0 deletions src/actors/ghost.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
;;;=========================================================================;;;
;;; Copyright 2022 Matthew D. Steele <[email protected]> ;;;
;;; ;;;
;;; This file is part of Annalog. ;;;
;;; ;;;
;;; Annalog is free software: you can redistribute it and/or modify it ;;;
;;; under the terms of the GNU General Public License as published by the ;;;
;;; Free Software Foundation, either version 3 of the License, or (at your ;;;
;;; option) any later version. ;;;
;;; ;;;
;;; Annalog is distributed in the hope that it will be useful, but WITHOUT ;;;
;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ;;;
;;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ;;;
;;; for more details. ;;;
;;; ;;;
;;; You should have received a copy of the GNU General Public License along ;;;
;;; with Annalog. If not, see <http://www.gnu.org/licenses/>. ;;;
;;;=========================================================================;;;

.INCLUDE "../macros.inc"
.INCLUDE "../ppu.inc"
.INCLUDE "ghost.inc"
.INCLUDE "orc.inc"
.INCLUDE "townsfolk.inc"

.IMPORT Data_PowersOfTwo_u8_arr8
.IMPORT FuncA_Objects_BobActorShapePosUpAndDown
.IMPORT FuncA_Objects_Draw2x2Shape
.IMPORT FuncA_Objects_Draw2x3TownsfolkShape
.IMPORT FuncA_Objects_MoveShapeHorz
.IMPORT FuncA_Objects_MoveShapeUpByA
.IMPORT FuncA_Objects_MoveShapeVert
.IMPORT FuncA_Objects_SetShapePosToActorCenter
.IMPORT Func_Cosine
.IMPORT Func_InitActorWithState1
.IMPORT Func_Noop
.IMPORT Func_SignedMult
.IMPORT Func_Sine
.IMPORT Ram_ActorFlags_bObj_arr
.IMPORT Ram_ActorState1_byte_arr
.IMPORT Ram_ActorState2_byte_arr

;;;=========================================================================;;;

.SEGMENT "PRGA_Room"

;;; Turns an NPC mermaid ghost or orc ghost into a ghost baddie, and then makes
;;; it disappear.
;;; @param X The actor index.
;;; @param Y The new actor type for the ghost (BadGhostMermaid or BadGhostOrc).
.EXPORT FuncA_Room_MakeNpcGhostDisappear
.PROC FuncA_Room_MakeNpcGhostDisappear
lda #eBadGhost::Disappearing ; param: eBadGhost value
jsr Func_InitActorWithState1 ; preserves X
;; TODO: Make the ghost baddie face the player avatar.
;; TODO: Play a sound
rts
.ENDPROC

;;;=========================================================================;;;

.SEGMENT "PRGA_Actor"

;;; Performs per-frame updates for an orc ghost baddie actor.
;;; @param X The actor index.
;;; @preserve X
.EXPORT FuncA_Actor_TickBadGhostMermaid
.PROC FuncA_Actor_TickBadGhostMermaid
ldy Ram_ActorState1_byte_arr, x ; current eBadGhost mode
lda _JumpTable_ptr_0_arr, y
sta T0
lda _JumpTable_ptr_1_arr, y
sta T1
jmp (T1T0)
.REPEAT 2, table
D_TABLE_LO table, _JumpTable_ptr_0_arr
D_TABLE_HI table, _JumpTable_ptr_1_arr
D_TABLE .enum, eBadGhost
d_entry table, Absent, Func_Noop
d_entry table, Idle, Func_Noop
d_entry table, Disappearing, FuncA_Actor_TickBadGhost_Disappearing
d_entry table, Reappearing, FuncA_Actor_TickBadGhost_Reappearing
D_END
.ENDREPEAT
.ENDPROC

;;; Performs per-frame updates for an orc ghost baddie actor.
;;; @param X The actor index.
;;; @preserve X
.EXPORT FuncA_Actor_TickBadGhostOrc
.PROC FuncA_Actor_TickBadGhostOrc
ldy Ram_ActorState1_byte_arr, x ; current eBadGhost mode
lda _JumpTable_ptr_0_arr, y
sta T0
lda _JumpTable_ptr_1_arr, y
sta T1
jmp (T1T0)
.REPEAT 2, table
D_TABLE_LO table, _JumpTable_ptr_0_arr
D_TABLE_HI table, _JumpTable_ptr_1_arr
D_TABLE .enum, eBadGhost
d_entry table, Absent, Func_Noop
d_entry table, Idle, Func_Noop
d_entry table, Disappearing, FuncA_Actor_TickBadGhost_Disappearing
d_entry table, Reappearing, FuncA_Actor_TickBadGhost_Reappearing
D_END
.ENDREPEAT
.ENDPROC

;;; Performs per-frame updates for a mermaid/orc ghost baddie actor that's in
;;; Disappearing mode.
;;; @param X The actor index.
;;; @preserve X
.PROC FuncA_Actor_TickBadGhost_Disappearing
;; Increment timer until it reaches its end value.
inc Ram_ActorState2_byte_arr, x ; mode timer
lda Ram_ActorState2_byte_arr, x ; mode timer
cmp #kBadGhostAppearFrames
blt @done
;; When the timer finishes, make the ghost absent (and clear its timer).
lda #eBadGhost::Absent
sta Ram_ActorState1_byte_arr, x ; current eBadGhost mode
.assert eBadGhost::Absent = 0, error
sta Ram_ActorState2_byte_arr, x ; mode timer
@done:
rts
.ENDPROC

;;; Performs per-frame updates for a mermaid/orc ghost baddie actor that's in
;;; Disappearing mode.
;;; @param X The actor index.
;;; @preserve X
.PROC FuncA_Actor_TickBadGhost_Reappearing
;; Increment timer until it reaches zero.
dec Ram_ActorState2_byte_arr, x ; mode timer
bne @done
;; When the timer finishes, make the ghost idle. Its timer will already be
;; clear.
lda #eBadGhost::Idle
sta Ram_ActorState1_byte_arr, x ; current eBadGhost mode
@done:
rts
.ENDPROC

;;;=========================================================================;;;

.SEGMENT "PRGA_Objects"

;;; Draws a mermaid ghost baddie actor.
;;; @param X The actor index.
;;; @preserve X
.EXPORT FuncA_Objects_DrawActorBadGhostMermaid
.PROC FuncA_Objects_DrawActorBadGhostMermaid
jsr FuncA_Objects_SetShapePosToBadGhostCenter ; preserves X; returns Y, Z
beq FuncA_Objects_DrawActorBadGhostAbsent ; preserves X
lda _FirstTileId_u8_arr, y ; param: first tile ID
ldy Ram_ActorFlags_bObj_arr, x ; param: object flags
jmp FuncA_Objects_Draw2x3TownsfolkShape ; preserves X
_FirstTileId_u8_arr:
D_ARRAY .enum, eBadGhost
d_byte Absent, kTileIdMermaidGhostFirst + 0
d_byte Idle, kTileIdMermaidGhostFirst + 0
d_byte Disappearing, kTileIdMermaidGhostFirst + 0
d_byte Reappearing, kTileIdMermaidGhostFirst + 0
D_END
.ENDPROC

;;; Draws a ghost baddie actor that's absent (invisible). In other words, this
;;; is a no-op.
;;; @param X The actor index.
;;; @preserve X
.PROC FuncA_Objects_DrawActorBadGhostAbsent
rts
.ENDPROC

;;; Draws an orc ghost baddie actor.
;;; @param X The actor index.
;;; @preserve X
.EXPORT FuncA_Objects_DrawActorBadGhostOrc
.PROC FuncA_Objects_DrawActorBadGhostOrc
jsr FuncA_Objects_SetShapePosToBadGhostCenter ; preserves X; returns Y, Z
beq FuncA_Objects_DrawActorBadGhostAbsent ; preserves X
;; Draw feet:
lda _FirstTileId_u8_arr, y ; param: first tile ID
jsr _DrawPart ; preserves X
;; Draw head:
lda #kBlockHeightPx
jsr FuncA_Objects_MoveShapeUpByA ; preserves X and T0+
lda #kTileIdObjOrcGhostFirst + 0 ; param: first tile ID
_DrawPart:
ldy Ram_ActorFlags_bObj_arr, x ; param: object flags
jmp FuncA_Objects_Draw2x2Shape ; preserves X
_FirstTileId_u8_arr:
D_ARRAY .enum, eBadGhost
d_byte Absent, kTileIdObjOrcGhostFirst + 4
d_byte Idle, kTileIdObjOrcGhostFirst + 4
d_byte Disappearing, kTileIdObjOrcGhostFirst + 4
d_byte Reappearing, kTileIdObjOrcGhostFirst + 4
D_END
.ENDPROC

;;; Sets the shape position for a ghost baddie actor, taking its current mode
;;; into account (and also returning that mode, for convenience).
;;; @param X The actor index.
;;; @return Y The actor's current eBadGhost mode.
;;; @return Z Set if the ghost is in Absent mode, and thus should not be drawn.
;;; @preserve X
.PROC FuncA_Objects_SetShapePosToBadGhostCenter
jsr FuncA_Objects_SetShapePosToActorCenter ; preserves X
jsr FuncA_Objects_BobActorShapePosUpAndDown ; preserves X
ldy Ram_ActorState1_byte_arr, x ; current eBadGhost mode
.assert eBadGhost::Absent = 0, error
beq @done ; Z is set: ghost is absent
cpy #eBadGhost::Disappearing
beq @displace
cpy #eBadGhost::Reappearing
bne @done ; Z is clear: ghost is not absent
@displace:
;; Horizontal displacement:
lda Ram_ActorState2_byte_arr, x ; mode timer
mul #2
sta T2 ; displacement radius
mul #8
bit Data_PowersOfTwo_u8_arr8 + 4
beq @setAngle
eor #$80
@setAngle:
pha ; param: displacement angle
jsr Func_Cosine ; preserves X, T0+; returns A (param: signed multiplicand)
ldy T2 ; displacement radius (param: unsigned multiplier)
jsr Func_SignedMult ; preserves X and T2+; returns YA
tya ; param: signed offset
jsr FuncA_Objects_MoveShapeHorz ; preserves X and T0+
;; Vertical displacement:
pla ; angle
jsr Func_Sine ; preserves X, T0+; returns A (param: signed multiplicand)
ldy T2 ; displacement radius (param: unsigned multiplier)
jsr Func_SignedMult ; preserves X, returns YA
tya ; param: signed offset
jsr FuncA_Objects_MoveShapeVert ; preserves X
;; Set up Y and Z return values again:
ldy Ram_ActorState1_byte_arr, x ; current eBadGhost mode
@done:
rts
.ENDPROC

;;;=========================================================================;;;
44 changes: 44 additions & 0 deletions src/actors/ghost.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
;;;=========================================================================;;;
;;; Copyright 2022 Matthew D. Steele <[email protected]> ;;;
;;; ;;;
;;; This file is part of Annalog. ;;;
;;; ;;;
;;; Annalog is free software: you can redistribute it and/or modify it ;;;
;;; under the terms of the GNU General Public License as published by the ;;;
;;; Free Software Foundation, either version 3 of the License, or (at your ;;;
;;; option) any later version. ;;;
;;; ;;;
;;; Annalog is distributed in the hope that it will be useful, but WITHOUT ;;;
;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ;;;
;;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ;;;
;;; for more details. ;;;
;;; ;;;
;;; You should have received a copy of the GNU General Public License along ;;;
;;; with Annalog. If not, see <http://www.gnu.org/licenses/>. ;;;
;;;=========================================================================;;;

;;; State bytes for mermaid/orc ghost baddies:
;;; * Param: The initial eBadGhost value to set for State1.
;;; * Flags: The bObj::FlipH bit is set if the ghost is facing left, or
;;; cleared if it is facing right.
;;; * State1: The eBadGhost value for the ghost's current behavior mode.
;;; * State2: A timer for the current mode that increments or decrements each
;;; frame, depending on the mode.
;;; * State3: Unused.
;;; * State4: Unused.

;;;=========================================================================;;;

;;; Possible values for a ghost baddie actor's State1 byte.
.ENUM eBadGhost
Absent ; invisible, waiting for a new mode to be set
Idle ; visible, waiting for a new mode to be set
Disappearing ; disappearing
Reappearing ; reappearing
NUM_VALUES
.ENDENUM

;;; How many frames it takes a ghost baddie actor to appear or disappear.
kBadGhostAppearFrames = 45

;;;=========================================================================;;;
3 changes: 1 addition & 2 deletions src/actors/townsfolk.asm
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ kPaletteObjMermaidQueenHead = 1
cmp #kFirst2x4MermaidTileId
blt FuncA_Objects_Draw2x3TownsfolkShape ; preserves X
jmp FuncA_Objects_Draw2x4TownsfolkShape ; preserves X
_VertOffset_u8_arr8:
.byte 0, 0, 0, 1, 2, 2, 2, 1
.ENDPROC

;;; Draws a mermaid queen NPC actor.
Expand Down Expand Up @@ -105,6 +103,7 @@ _BottomHalf:
;;; @param A The first tile ID.
;;; @param Y The object flags to use.
;;; @preserve X
.EXPORT FuncA_Objects_Draw2x3TownsfolkShape
.PROC FuncA_Objects_Draw2x3TownsfolkShape
sta T2 ; first tile ID
sty T3 ; object flags
Expand Down
Loading

0 comments on commit 377d1ae

Please sign in to comment.