Prev: CD34 Up: Map Next: CE64
CD50: Handle Homing Enemy
Per-frame entity handler for a homing enemy. Each frame the entity moves one step toward the player. If it catches another entity it removes that entity from play, awards the player points, and shows a floating score popup. If it reaches the player it triggers the player death sequence.
Handle_Homing_Enemy CD50 LD A,($C533) Read the wave start delay from Wave_Start_Delay.
CD53 AND A Jump to Process_Entity_Record_Counter_Up_Next7 if the wave has not started yet.
CD54 JP NZ,Process_Entity_Record_Counter_Up_Next7
CD57 CALL Generate_Random_Byte Generate a random movement delay value.
CD5A AND %00001111 Keep the low four bits (delay range 00–0F).
CD5C INC A Increment to give a delay range of 01–10.
CD5D LD ($C4F6),HL Stash the entity record pointer and load the delay into B.
CD60 LD B,A
CD61 LD A,($C51C) Read the animation frame counter from C51C.
CD64 SUB B Skip movement this frame if the frame counter has not yet reached the delay value.
CD65 JP NC,Handle_Homing_Enemy_Advance
CD68 INC HL Step past the handler address and erase the entity sprite.
CD69 CALL Erase_Entity_Sprite
CD6C LD HL,($C4F6) Restore the entity record pointer and advance to the entity position bytes.
CD6F INC HL
CD70 INC HL
Move the entity one step toward the player along both axes.
CD71 LD A,($C4D4) Compute the vertical distance from this entity to the player.
CD74 SUB (HL)
CD75 LD A,($C426) Load the vertical movement speed and negate it if the entity is above the player.
CD78 JR NC,Handle_Homing_Enemy_Apply_Y
CD7A NEG
Handle_Homing_Enemy_Apply_Y CD7C ADD A,(HL) Apply the vertical delta and step to the X position byte.
CD7D LD (HL),A
CD7E INC HL
CD7F LD A,($C4D5) Compute the horizontal distance from this entity to the player.
CD82 SUB (HL)
CD83 LD A,($C426) Load the horizontal movement speed and negate it if the entity is to the right of the player.
CD86 JR NC,Handle_Homing_Enemy_Apply_X
CD88 NEG
Handle_Homing_Enemy_Apply_X CD8A ADD A,(HL) Apply the horizontal delta to the entity X position.
CD8B LD (HL),A
CD8C DEC HL Step back to the entity Y position.
CD8D DEC HL
CD8E EXX Set the draw colour to 46 in the shadow registers.
CD8F LD B,$46
CD91 EXX
CD92 CALL Draw_Entity_Sprite Redraw the entity sprite at its new position.
CD95 LD HL,($C4F6) Restore the entity record pointer.
Handle_Homing_Enemy_Advance CD98 INC HL Advance the entity record pointer by two bytes.
CD99 INC HL
CD9A EXX Jump to Handle_Homing_Enemy_Caught_Entity if this entity has caught another entity in the list.
CD9B CALL Find_Colliding_Entity
CD9E JR NC,Handle_Homing_Enemy_Caught_Entity
CDA0 LD HL,$C4D4 Point to the player position data and switch to the shadow registers.
CDA3 EXX
CDA4 CALL HitTestBounds8AtHL Trigger the player death sequence if this entity has reached the player.
CDA7 JP NC,Strip_Attributes_And_Fade
CDAA INC HL Advance the entity pointer and return.
CDAB INC HL
CDAC RET
This entity has reached another entity; remove the caught entity from play, award the player points, and display a floating score popup.
Handle_Homing_Enemy_Caught_Entity CDAD LD DE,$0006 Step back six bytes to the start of the caught entity's record.
CDB0 SBC HL,DE
CDB2 LD ($C4DA),HL Save the caught entity's record pointer to Entity_Record_Pointer.
CDB5 CALL Erase_Narrow_Entity_Sprite Erase the caught entity's sprite.
CDB8 CALL Remove_Entity_From_List Remove the caught entity from the entity list.
CDBB LD HL,$C41C Decrement the active enemy count at Active_Enemy_Count.
CDBE DEC (HL)
CDBF LD HL,$C425 Decrement the wave entity kill counter.
CDC2 DEC (HL)
CDC3 EXX Install the score popup handler and update the entity state in the shadow record.
CDC4 DEC HL
CDC5 DEC HL
CDC6 LD (HL),$02
CDC8 DEC HL
CDC9 LD DE,$CE1F
CDCC LD (HL),D
CDCD DEC HL
CDCE LD (HL),E
CDCF INC HL Step forward to the entity position byte.
CDD0 INC HL
CDD1 INC HL
CDD2 PUSH HL Erase the score popup sprite.
CDD3 CALL Erase_Entity_Sprite
CDD6 POP HL
CDD7 INC HL Step to the entity Y position byte.
CDD8 EXX Set the draw colour to 02 in the shadow registers.
CDD9 LD B,$02
CDDB EXX
CDDC LD A,(HL) Clamp the score popup Y position within the play area.
CDDD SUB $06
CDDF CP $10
CDE1 JR C,Handle_Homing_Enemy_1
CDE3 CP $B9
CDE5 JR C,Handle_Homing_Enemy_0
CDE7 SUB $06
Handle_Homing_Enemy_0 CDE9 LD (HL),A
Handle_Homing_Enemy_1 CDEA DEC HL
CDEB PUSH HL Draw the score popup sprite at the entity's position.
CDEC CALL Draw_Clipped_Wide_Sprite
CDEF POP HL
CDF0 LD DE,$0006 Step forward to the player's BCD score bytes.
CDF3 ADD HL,DE
Award the player points for catching the entity; add the point value to the BCD score with carry propagation through all four score bytes.
CDF4 EXX Add the enemy's point value to the least significant BCD score byte.
CDF5 LD HL,$C406
CDF8 LD A,(HL)
CDF9 ADD A,$00
CDFB DAA
CDFC LD (HL),A
CDFD LD A,$01 Propagate BCD carry from the lowest score byte into the next score byte.
CDFF DEC HL
CE00 JR NC,Handle_Homing_Enemy_2
CE02 INC A
Handle_Homing_Enemy_2 CE03 ADD A,(HL)
CE04 DAA
CE05 LD (HL),A
CE06 JR NC,Handle_Homing_Enemy_3
CE08 DEC HL Propagate BCD carry through the second score byte.
CE09 LD A,$01
CE0B ADD A,(HL)
CE0C DAA
CE0D LD (HL),A
CE0E JR NC,Handle_Homing_Enemy_3
CE10 DEC HL Propagate BCD carry into the most significant score byte.
CE11 LD A,$01
CE13 DAA
CE14 LD (HL),A
Handle_Homing_Enemy_3 CE15 CALL Clear_Colour_Bar_Column Refresh the score display column.
CE18 LD E,$00 Initialise the score popup entity state via Initialise_Entity_State.
CE1A CALL Initialise_Entity_State
CE1D EXX Restore the main register set and return.
CE1E RET
Per-frame handler for the floating score popup; scrolls the popup upward each frame until 0F frames have elapsed.
Handle_Homing_Enemy_Float_Score CE1F LD A,(HL) Load the entity state byte into shadow B'.
CE20 EXX
CE21 LD B,A
CE22 EXX
CE23 PUSH HL Draw the score popup sprite at the current entity position.
CE24 INC HL
CE25 CALL Draw_Clipped_Wide_Sprite
CE28 POP HL
CE29 INC (HL) Advance the animation frame and jump to Handle_Homing_Enemy_Float_Score_Exit when the score popup has completed.
CE2A LD A,(HL)
CE2B CP $0F
CE2D JR Z,Handle_Homing_Enemy_Float_Score_Exit
CE2F EXX Update shadow B' with the frame count and advance to the entity Y position.
CE30 LD B,A
CE31 EXX
CE32 INC HL
CE33 INC HL
CE34 LD A,(HL) Select the vertical scroll speed based on the Y position.
CE35 CP $16
CE37 JR NC,Handle_Homing_Enemy_4
CE39 CP $AD
CE3B LD A,$00
CE3D JR NC,Handle_Homing_Enemy_Float_Score_Done
CE3F JR Handle_Homing_Enemy_Float_Score_Move
Handle_Homing_Enemy_4 CE41 CP $B0 Adjust the scroll speed for the upper boundary.
CE43 LD A,$FA
CE45 JR C,Handle_Homing_Enemy_Float_Score_Move
CE47 LD A,$F4
Handle_Homing_Enemy_Float_Score_Move CE49 ADD A,(HL) Apply the Y delta, redraw the score popup, and continue at Process_Entity_Record_Next6.
CE4A LD (HL),A
CE4B DEC HL
CE4C PUSH HL
CE4D CALL Draw_Clipped_Wide_Sprite
CE50 POP HL
CE51 JP Process_Entity_Record_Next6
Handle_Homing_Enemy_Float_Score_Done CE54 DEC HL Step back to the handler address field.
CE55 DEC HL
Handle_Homing_Enemy_Float_Score_Exit CE56 LD DE,$E02C Install Process_Entity_Record_Next7 as the score popup completion handler.
CE59 DEC HL
CE5A LD (HL),D
CE5B DEC HL
CE5C LD (HL),E
CE5D INC HL
CE5E INC HL
CE5F JP Process_Entity_Record_Next7 Jump to Process_Entity_Record_Next7 to finalise the score popup.
CE62 POP DE Return.
CE63 RET
Prev: CD34 Up: Map Next: CE64