Prev: 69A7 Up: Map Next: 6AF6
69F7: Handler: Red Bird
Used by the routine at Run_Main_Loop_Body.
Handles the red bird who is a thief that steals worms Percy is carrying.
Percy can stun the red bird by hitting it with an egg. The red bird's flight path data is stored at Table_RedBirdFlightPath_01 with entries separated by 00 terminators for each room.
Handler_RedBird 69F7 LD A,($5FBB) Jump to HandleRedBird_Update if *RespawnFlag is not set.
69FA OR A
69FB JR Z,HandleRedBird_Update
Initialise the red bird for the current room. Scan through the flight path data at Table_RedBirdFlightPath_01, skipping past 00 terminators until the entry for the current room is found.
69FD LD HL,$BE00 Point HL at Table_RedBirdFlightPath_01.
6A00 LD A,($5FC5) Load A and E with *CurrentRoom.
6A03 LD E,A
6A04 LD B,$01 Set a room counter in B starting at 01.
6A06 CP B Jump to HandleRedBird_InitPath if this is room 01 (data starts here).
6A07 JR Z,HandleRedBird_InitPath
Scan through the flightpath data to find the current room.
HandleRedBird_ScanLoop 6A09 LD A,(HL) A=*HL.
6A0A INC HL Advance the data pointer.
6A0B OR A Jump back to HandleRedBird_ScanLoop if this byte isn't the terminator (00).
6A0C JP NZ,HandleRedBird_ScanLoop
Found a 00 terminator so move to the data for the next room.
6A0F INC B Increment the room counter.
6A10 LD A,E Jump back to HandleRedBird_ScanLoop if this isn't at the target room yet.
6A11 CP B
6A12 JR NZ,HandleRedBird_ScanLoop
Found the correct room's data so store the flight path pointer.
HandleRedBird_InitPath 6A14 LD ($6CBB),HL Write HL to *Pointer_RedBirdFlightpathData (current flight path pointer).
Seed the random animation state from the Memory Refresh Register.
HandleRedBird_SetAnimationSeed 6A17 LD A,R Write the contents of the Memory Refresh Register to *RedBirdAnimationSeed.
6A19 LD ($6CB7),A
Update the red bird's position and check for collisions.
HandleRedBird_Update 6A1C CALL UpdateRedBirdMovement Call UpdateRedBirdMovement.
Check if the red bird has stolen Percy's worm.
6A1F LD A,($6CB4) Jump to HandleRedBird_CheckEgg if *RedBirdStunTimer is set so the red bird is already stunned/ caught.
6A22 OR A
6A23 JR NZ,HandleRedBird_CheckEgg
6A25 LD A,($5FAA) Jump to HandleRedBird_CheckEgg if *CarryingWormFlag is unset.
6A28 OR A
6A29 JR Z,HandleRedBird_CheckEgg
Check collision between Percy and the red bird.
6A2B LD IX,$DAC0 IX=Percy_X_Position (Percy's sprite data).
6A2F LD IY,$DAC4 IY=Sprite01_3Wide_X_Position (red bird sprite data).
6A33 CALL CheckSpriteCollision Call CheckSpriteCollision.
6A36 JR C,HandleRedBird_CheckEgg Jump to HandleRedBird_CheckEgg if no collision.
Check the red bird has a valid frame (is visible).
6A38 LD A,(IY+$03) Jump to HandleRedBird_CheckEgg if *IY+03 is unset, so the red bird frame is 00 (i.e. not visible).
6A3B OR A
6A3C JR Z,HandleRedBird_CheckEgg
Red bird stole Percy's worm so return the worm to the room and play a sound.
6A3E CALL DropWorm Call DropWorm.
6A41 LD DE,$0003 DE=0003.
6A44 LD HL,$00C8 HL=00C8 (initial beep pitch).
6A47 LD B,$0A Set a sound step counter in B of 0A steps.
HandleRedBird_StolenSound 6A49 PUSH BC Stash the step counter, pitch and duration on the stack.
6A4A PUSH HL
6A4B PUSH DE
6A4C LD IY,$5C3D IY=ERR_SP.
6A50 CALL $03B5 Call BEEP.
6A53 DI Disable interrupts.
6A54 POP DE Restore the duration and pitch from the stack.
6A55 POP HL
6A56 LD BC,$0012 HL=0012 (raise the pitch for the next step).
6A59 ADD HL,BC
6A5A POP BC Restore the step counter from the stack.
6A5B DJNZ HandleRedBird_StolenSound Decrease the step counter by one and loop back to HandleRedBird_StolenSound until the sound is complete.
6A5D NOP No operation.
6A5E NOP
6A5F NOP
Check if Percy's egg has hit the red bird.
HandleRedBird_CheckEgg 6A60 LD A,($5FA9) Jump to HandleRedBird_Done if *EggDropFlag is unset/ no egg is active.
6A63 OR A
6A64 JR Z,HandleRedBird_Done
6A66 LD IY,$DAE0 IY=Egg_X_Position.
6A6A LD IX,$DAC4 IX=Sprite01_3Wide_X_Position.
Only check collision if the red bird is in the same room as the egg.
6A6E LD A,($6CB6) B=*RedBirdCurrentRoom.
6A71 LD B,A
6A72 LD A,($5FC5) A=*CurrentRoom.
6A75 CP B Jump to HandleRedBird_Done if the red bird is not in the current room.
6A76 JR NZ,HandleRedBird_Done
The red bird is in the current room.
6A78 CALL CheckEggCollision Call CheckEggCollision.
6A7B JR C,HandleRedBird_Done Jump to HandleRedBird_Done if no collision.
Egg hit the red bird so check if already stunned.
6A7D LD A,($6CB4) Jump to HandleRedBird_CancelEgg if *RedBirdStunTimer is set so the red bird is already stunned.
6A80 OR A
6A81 JR NZ,HandleRedBird_CancelEgg
Stun the red bird so set a random stun timer and award points.
6A83 CALL GenerateRandomNumber Call GenerateRandomNumber.
6A86 OR %01000000 Set bit 6 (ensure a minimum stun duration).
6A88 LD ($6CB4),A Write A to *RedBirdStunTimer.
6A8B LD ($6CB5),A Write A to *RedBirdStunTimerCopy.
6A8E LD (IX+$02),$01 Write 01 to *IX+02 (stunned colour: BLUE).
6A92 LD A,$14 Call AddToScore to add 14 points to the score.
6A94 CALL AddToScore
6A97 CALL PlayHitSound Call PlayHitSound.
Cancel the egg.
HandleRedBird_CancelEgg 6A9A CALL CancelEggDrop Call CancelEggDrop.
HandleRedBird_Done 6A9D CALL Handle_Butterfly Call Handle_Butterfly.
6AA0 RET Return.
This entry point is used by the routine at UpdateRedBirdMovement.
Calculates the red bird's next room and flight direction when it crosses a room boundary. Also looks up the flight speed for the current level and finds a valid starting position.
HandleRedBird_SetupFlight 6AA1 LD A,($5FC5) B=*CurrentRoom.
6AA4 LD B,A
6AA5 LD A,($6CB6) A=*RedBirdCurrentRoom.
Check if the combined value wraps past room 0B.
6AA8 ADD A,B A+=B.
6AA9 CP $0C Jump to HandleRedBird_LookupSpeed if the combined value doesn't wrap past room 0B.
6AAB JR NZ,HandleRedBird_LookupSpeed
Wrap point reached so flip the red bird's flight direction.
6AAD LD A,($6CB3) A=*RedBirdTraversalDirection.
6AB0 XOR %00000001 Toggle bit 0 (flip direction).
6AB2 LD ($6CB3),A Write A to *RedBirdTraversalDirection.
Look up the flight speed for the current level from the table at RedBirdSpeedTable.
HandleRedBird_LookupSpeed 6AB5 LD HL,$6CBE HL=RedBirdSpeedTable.
6AB8 LD A,($5FB1) A=*CurrentLevel.
6ABB DEC A Decrement to make zero-indexed.
6ABC LD E,A E=A.
6ABD LD D,$00 D=00.
6ABF ADD HL,DE HL+=DE.
6AC0 LD A,(HL) A=*HL (flight speed for this level).
6AC1 LD ($6CB9),A Write A to *RedBirdFlightSpeed.
Set up the starting position based on the flight direction.
6AC4 LD A,($6CB3) A=*RedBirdTraversalDirection.
6AC7 LD C,$E6 C=E6 (starting X for rightward flight).
6AC9 LD B,$06 B=06 (starting Y).
6ACB OR A Jump to HandleRedBird_FindPosition if flying right (direction is non-zero).
6ACC JR NZ,HandleRedBird_FindPosition
6ACE LD C,$06 C=06 (starting X for leftward flight).
Search for a valid Y position that doesn't collide with scenery.
HandleRedBird_FindPosition 6AD0 CALL Validate_Position Call Validate_Position.
6AD3 RET NC Return if no collision (valid position found).
Position blocked so try the next row down.
6AD4 INC B Increment B by 04.
6AD5 INC B
6AD6 INC B
6AD7 INC B
6AD8 LD A,B A=B.
6AD9 CP $50 Jump back to HandleRedBird_FindPosition until the bottom of search area is reached.
6ADB JR C,HandleRedBird_FindPosition
Reached the bottom so wrap back to the top and shift X inward.
6ADD LD B,$04 B=04 (reset Y to the top).
6ADF LD A,($6CB3) A=*RedBirdTraversalDirection (flight direction).
6AE2 OR A Jump to HandleRedBird_ShiftLeft if flying right.
6AE3 JR NZ,HandleRedBird_ShiftLeft
Flying left so shift the starting X position rightward.
6AE5 INC C Increment C by 06.
6AE6 INC C
6AE7 INC C
6AE8 INC C
6AE9 INC C
6AEA INC C
6AEB JR HandleRedBird_FindPosition Jump to HandleRedBird_FindPosition to try again.
Flying right so shift the starting X position leftward.
HandleRedBird_ShiftLeft 6AED DEC C Decrement C by 06.
6AEE DEC C
6AEF DEC C
6AF0 DEC C
6AF1 DEC C
6AF2 DEC C
6AF3 JR HandleRedBird_FindPosition Jump to HandleRedBird_FindPosition to try again.
6AF5 RET Return.
Prev: 69A7 Up: Map Next: 6AF6