Prev: 27047 Up: Map Next: 27382
27127: 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 0 terminators for each room.
Handler_RedBird 27127 LD A,(24507) Jump to HandleRedBird_Update if *RespawnFlag is not set.
27130 OR A
27131 JR Z,HandleRedBird_Update
Initialise the red bird for the current room. Scan through the flight path data at Table_RedBirdFlightPath_01, skipping past 0 terminators until the entry for the current room is found.
27133 LD HL,48640 Point HL at Table_RedBirdFlightPath_01.
27136 LD A,(24517) Load A and E with *CurrentRoom.
27139 LD E,A
27140 LD B,1 Set a room counter in B starting at 1.
27142 CP B Jump to HandleRedBird_InitPath if this is room 1 (data starts here).
27143 JR Z,HandleRedBird_InitPath
Scan through the flightpath data to find the current room.
HandleRedBird_ScanLoop 27145 LD A,(HL) A=*HL.
27146 INC HL Advance the data pointer.
27147 OR A Jump back to HandleRedBird_ScanLoop if this byte isn't the terminator (0).
27148 JP NZ,HandleRedBird_ScanLoop
Found a 0 terminator so move to the data for the next room.
27151 INC B Increment the room counter.
27152 LD A,E Jump back to HandleRedBird_ScanLoop if this isn't at the target room yet.
27153 CP B
27154 JR NZ,HandleRedBird_ScanLoop
Found the correct room's data so store the flight path pointer.
HandleRedBird_InitPath 27156 LD (27835),HL Write HL to *Pointer_RedBirdFlightpathData (current flight path pointer).
Seed the random animation state from the Memory Refresh Register.
HandleRedBird_SetAnimationSeed 27159 LD A,R Write the contents of the Memory Refresh Register to *RedBirdAnimationSeed.
27161 LD (27831),A
Update the red bird's position and check for collisions.
HandleRedBird_Update 27164 CALL UpdateRedBirdMovement Call UpdateRedBirdMovement.
Check if the red bird has stolen Percy's worm.
27167 LD A,(27828) Jump to HandleRedBird_CheckEgg if *RedBirdStunTimer is set so the red bird is already stunned/ caught.
27170 OR A
27171 JR NZ,HandleRedBird_CheckEgg
27173 LD A,(24490) Jump to HandleRedBird_CheckEgg if *CarryingWormFlag is unset.
27176 OR A
27177 JR Z,HandleRedBird_CheckEgg
Check collision between Percy and the red bird.
27179 LD IX,56000 IX=Percy_X_Position (Percy's sprite data).
27183 LD IY,56004 IY=Sprite01_3Wide_X_Position (red bird sprite data).
27187 CALL CheckSpriteCollision Call CheckSpriteCollision.
27190 JR C,HandleRedBird_CheckEgg Jump to HandleRedBird_CheckEgg if no collision.
Check the red bird has a valid frame (is visible).
27192 LD A,(IY+3) Jump to HandleRedBird_CheckEgg if *IY+3 is unset, so the red bird frame is 0 (i.e. not visible).
27195 OR A
27196 JR Z,HandleRedBird_CheckEgg
Red bird stole Percy's worm so return the worm to the room and play a sound.
27198 CALL DropWorm Call DropWorm.
27201 LD DE,3 DE=0003.
27204 LD HL,200 HL=0200 (initial beep pitch).
27207 LD B,10 Set a sound step counter in B of 10 steps.
HandleRedBird_StolenSound 27209 PUSH BC Stash the step counter, pitch and duration on the stack.
27210 PUSH HL
27211 PUSH DE
27212 LD IY,23613 IY=ERR_SP.
27216 CALL 949 Call BEEP.
27219 DI Disable interrupts.
27220 POP DE Restore the duration and pitch from the stack.
27221 POP HL
27222 LD BC,18 HL=0018 (raise the pitch for the next step).
27225 ADD HL,BC
27226 POP BC Restore the step counter from the stack.
27227 DJNZ HandleRedBird_StolenSound Decrease the step counter by one and loop back to HandleRedBird_StolenSound until the sound is complete.
27229 NOP No operation.
27230 NOP
27231 NOP
Check if Percy's egg has hit the red bird.
HandleRedBird_CheckEgg 27232 LD A,(24489) Jump to HandleRedBird_Done if *EggDropFlag is unset/ no egg is active.
27235 OR A
27236 JR Z,HandleRedBird_Done
27238 LD IY,56032 IY=Egg_X_Position.
27242 LD IX,56004 IX=Sprite01_3Wide_X_Position.
Only check collision if the red bird is in the same room as the egg.
27246 LD A,(27830) B=*RedBirdCurrentRoom.
27249 LD B,A
27250 LD A,(24517) A=*CurrentRoom.
27253 CP B Jump to HandleRedBird_Done if the red bird is not in the current room.
27254 JR NZ,HandleRedBird_Done
The red bird is in the current room.
27256 CALL CheckEggCollision Call CheckEggCollision.
27259 JR C,HandleRedBird_Done Jump to HandleRedBird_Done if no collision.
Egg hit the red bird so check if already stunned.
27261 LD A,(27828) Jump to HandleRedBird_CancelEgg if *RedBirdStunTimer is set so the red bird is already stunned.
27264 OR A
27265 JR NZ,HandleRedBird_CancelEgg
Stun the red bird so set a random stun timer and award points.
27267 CALL GenerateRandomNumber Call GenerateRandomNumber.
27270 OR %01000000 Set bit 6 (ensure a minimum stun duration).
27272 LD (27828),A Write A to *RedBirdStunTimer.
27275 LD (27829),A Write A to *RedBirdStunTimerCopy.
27278 LD (IX+2),1 Write 1 to *IX+2 (stunned colour: BLUE).
27282 LD A,20 Call AddToScore to add 20 points to the score.
27284 CALL AddToScore
27287 CALL PlayHitSound Call PlayHitSound.
Cancel the egg.
HandleRedBird_CancelEgg 27290 CALL CancelEggDrop Call CancelEggDrop.
HandleRedBird_Done 27293 CALL Handle_Butterfly Call Handle_Butterfly.
27296 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 27297 LD A,(24517) B=*CurrentRoom.
27300 LD B,A
27301 LD A,(27830) A=*RedBirdCurrentRoom.
Check if the combined value wraps past room 11.
27304 ADD A,B A+=B.
27305 CP 12 Jump to HandleRedBird_LookupSpeed if the combined value doesn't wrap past room 11.
27307 JR NZ,HandleRedBird_LookupSpeed
Wrap point reached so flip the red bird's flight direction.
27309 LD A,(27827) A=*RedBirdTraversalDirection.
27312 XOR %00000001 Toggle bit 0 (flip direction).
27314 LD (27827),A Write A to *RedBirdTraversalDirection.
Look up the flight speed for the current level from the table at RedBirdSpeedTable.
HandleRedBird_LookupSpeed 27317 LD HL,27838 HL=RedBirdSpeedTable.
27320 LD A,(24497) A=*CurrentLevel.
27323 DEC A Decrement to make zero-indexed.
27324 LD E,A E=A.
27325 LD D,0 D=0.
27327 ADD HL,DE HL+=DE.
27328 LD A,(HL) A=*HL (flight speed for this level).
27329 LD (27833),A Write A to *RedBirdFlightSpeed.
Set up the starting position based on the flight direction.
27332 LD A,(27827) A=*RedBirdTraversalDirection.
27335 LD C,230 C=230 (starting X for rightward flight).
27337 LD B,6 B=6 (starting Y).
27339 OR A Jump to HandleRedBird_FindPosition if flying right (direction is non-zero).
27340 JR NZ,HandleRedBird_FindPosition
27342 LD C,6 C=6 (starting X for leftward flight).
Search for a valid Y position that doesn't collide with scenery.
HandleRedBird_FindPosition 27344 CALL Validate_Position Call Validate_Position.
27347 RET NC Return if no collision (valid position found).
Position blocked so try the next row down.
27348 INC B Increment B by 4.
27349 INC B
27350 INC B
27351 INC B
27352 LD A,B A=B.
27353 CP 80 Jump back to HandleRedBird_FindPosition until the bottom of search area is reached.
27355 JR C,HandleRedBird_FindPosition
Reached the bottom so wrap back to the top and shift X inward.
27357 LD B,4 B=4 (reset Y to the top).
27359 LD A,(27827) A=*RedBirdTraversalDirection (flight direction).
27362 OR A Jump to HandleRedBird_ShiftLeft if flying right.
27363 JR NZ,HandleRedBird_ShiftLeft
Flying left so shift the starting X position rightward.
27365 INC C Increment C by 6.
27366 INC C
27367 INC C
27368 INC C
27369 INC C
27370 INC C
27371 JR HandleRedBird_FindPosition Jump to HandleRedBird_FindPosition to try again.
Flying right so shift the starting X position leftward.
HandleRedBird_ShiftLeft 27373 DEC C Decrement C by 6.
27374 DEC C
27375 DEC C
27376 DEC C
27377 DEC C
27378 DEC C
27379 JR HandleRedBird_FindPosition Jump to HandleRedBird_FindPosition to try again.
27381 RET Return.
Prev: 27047 Up: Map Next: 27382